Disable RMI Dynamic code downloading (using codebase) on Applet - Performance issue - java

We are having a performance issue when loading our Swing application under an applet container.
The Swing client communicates with JBoss server using RMI protocol.
When comparing our webstart application VS the new Applet container , its seems that the
Object marshaling taking much more time in the applet.
The ObjectInputStream -> writeExternal (using the JBoss Client RMI infra ) taking too much time to complete , 3-5x times then the webstart
In our ENV we have full deployment that sync all JARS between the server and the client (applet or webstart) so we don't need to load them remotely
The applet tag look like this:
archive="[contain list of 100 JARS -> about 200 MB]"
codebase="http://[remoteApacheServer]/USERTEST:85600"
List item
List of params ...
When checked that on the applet bootstrap the Applet loaded all the JARS from the server
But checking with sniffer we saw that every time we marshaled a new Class the applet class loader didn't used the Local version and send another request to remoteApacheServer looking for the specific class.
We found out the solution for it: using applet parameter :
param name="codebase_lookup" value="false
also we saw that loading the JARS locally - setting local nodejs HTTP that will serve the JRAS and set the codebase to use this temp server also boostup the peformance .
even just create nodejs server that just proxying the request backto the original remoteApacheServer helped .
but still the performance is still not good :-(
we saw in the sniffer that the client sending a reqest every time with the applet codebase and the full list of archive (all 100 JARS) and we saw the RMI has a feature
(Dynamic code downloading using Java™ RMI) that the Server can Marshell an Object even if its not exists in its local CLASSPATH.
see RMI setttings here
Do you know any why to disable it - i think its can help use solving the performance issue.
maybe using the java.rmi.server.useCodebaseOnly ?

Related

Web appilcation connection to external server?

So I have two Java applications, a server and a client. They are simple programs no GUI elements just console applications. They work just fine running on my machine, and I have a client version that can even connect to the server via the internet.
Instead of hosting the Server on my local machine I would like to host it from a site like Openshift. Which I already have a HTML site up at using Tomcat 7. I would also like to be able to go to a page on the web server and have that page act as the client program.
I want to embedded the client program into the web server but....
How do I make the connection between the two servers? Pretty much how do I get the Web Page to reach out to the other server and make the connection(I am using sockets)? Do I need to be using a servlet, JSP, or something like Jquery?
If you feel like you need to see either the server program or the client let me know and I will post them.
I would like to host a client version on the web page.
Your JSP or servlet would be the client in that case, it would open a socket to the server process. Have a look at HttpServlet and its doGet method, this is basically what you would implement, and where you would place much of your client code, like opening a socket to your server process and returning data. You'll find tons of examples on the internet, see for instance
how to write hello world servlet Example
Browsing to the servlet's URL will invoke the doGet method and execute your client code. It should be stateless though, i.e. take whatever parameters are in the HttpServletRequest, do its thing based on that, and return as soon as possible. If your clients need to retain their connection to the server process, it will be a different story, and you may need for instance websockets (I have insufficient experience with that but it would sound like a good fit in that case).

Confirm understanding: Tomcat served applet, and app network traffic?

All..
I am hoping someone who can confirm for me, what I read and what I have observed, regarding the Tomcat Java applet server?
I have Linux server running Tomcat (I built two new ones, but based the configuration off the previous two that were present when I came on the job). I am fairly new to Tomcat servers -vs- web servers.
When a client connects to the Tomcat server address...
A static web page is served, with a link to a java applet:
When they click a link, Tomcat serves up an applet to the browser.
When the applet is served:
All connections and traffic that the applet creates is tunneled back to the Tomcat server? (pretty sure this is happening, and what is supposed to happen)
All connections connect through the client network connection? (All tests I have done can not confirm this.)
Is the tunneling a reason why Tomcat is used over just serving up the Java applet via a Apache server?
We have a SSL secure connection with certificates setup to allow https connections to the Tomcat server, and I am assuming all the data between Tomcat server and the applet is encrypted because of this?
Thanks!
There's no good reason from what you've told us so far to use Tomcat over a lighter httpd such as apache or nginx - if it's really just serving a Java applet and web page (static content). The former two are application servers, and as that implies that means a little more than just static content - although it will serve static content just fine, too. But there is no "Default" integration between the two technologies. In particular - your data will not be encrypted by default, you've got to make sure that your applet makes secure request. Serving the applet offer SSL only protects the connection that actually serves the applet, not subsequent ones - though there's no reason these shouldn't also go through the same SSL endpoint, the applet has to initiate that, there's nothing "magical" going on.
Here's a good article on when you'd want to use one or the other.
As for the other part - there is a security model that comes with an applet. By default, the applet will only be able to make connections back to the server from which it came - this is to prevent certain kinds of "cross-site" attacks which were seen in the past. These days, different sites interoperating are more common so there are many technologies you could use to for that, if you need to - but applets are largely considered outdated and not widely used - but your end user may also configure applets to get around this default policy.
Here is information about the appliet security model, including network restrictions.

Managing rest web app hostname urls in tomcat

This question might have been asked before as it is quite a common exercise, but I am not sure what to search with.
I have a rest client app hosted on one instance of Tomcat and a rest server hosted on a different tomcat instance on another hostname. This works well, but currently I have the hostname hardcoded in the java classes. How can I parameter-ize the host name inside the rest client so that it allows for a future change without restarting the tomcat on which the rest client is hosted ?
There are a number of solutions you could employ including (but not limited to):
look up the server hostname in a properties or xml file on the client server (each time you want to make a REST call)
provide a mechanism in the client app to configure the server hostname and store it in memory
look up the server hostname in a directory such as LDAP or AD or in a database (each time you want to make a REST call)
You could employ a caching mechanism if you don't want to look up the value every time - perhaps once it is read it only expires after a number of seconds/minutes, or after a number of calls.
A quite common technique to pass environment variables and even hostname is define a System variable that you could read using java.lang.System.getenv() or java.lang.System.getProperty() if you are using Maven once your application startup read this variable in a static class of constants so the value will be set at the beginning and remain until the end of the application there other techniques that involve, web.xml but to keep it simple this will work. Just add the var to the enviroment and read it.
You can always pass the host name in arguments during client process startup and then read those arguments using System.getProperty("hostName").

JAX-WS Endpoint to Domino

My Domino Web Service Provider broke when I upgraded the (Win64) server from 8.5.3FP2 to FP3. I wrote some information about it to XPage forum.
Instead of fighting with Axis based legacy stuff I'd like to use JAX WS which comes with Java 1.6. I decided to try this very simple example. I copy pasted the code to a Java project on my Designer Eclipse, run it and the Web Service was up and running on my local machine: it responded and returned the WSDL.
Next I copy pasted the code to an NSF on server as Code/Java elements and changed:
public static void main(String[] args)
to
public HelloWorldPublisher()
and called this constructor from SSJS in XPage. I got this error:
Exception in thread "main"
com.sun.xml.internal.ws.model.RuntimeModelerException : A
#WebService.targetNamespace must be specified on classes with no
package. Class: HelloWorldImpl
The classes were in packages. I run it also with command line on Domino server JVM and got the same error. After googling I added this
#WebService(targetNamespace="http://mycompany.net/dev/ph")
to HelloWorld and
#WebService(endpointInterface="com.mkyong.ws.HelloWorld", targetNamespace="http://mycompany.net/dev/ph", portName="HelloWorldPort", name="HelloWorld", serviceName="HelloWorldService")
to HelloWorldImpl in NSF and run it. After that the web service seemed to be up and running!
Next I booted the server because it was slow and after that I have not seen the WSDL! I've run the code many times, restarted HTTP and tried removing #WebService attributes. I've also tried to run the code with command line on server again but that gives me always the above #WebService.targetNamespace error, I have no idea why.
Now I get always this to Domino console:
java.lang.NoClassDefFoundError: com.sun.xml.internal.ws.api.streaming.XMLStreamWriterFactory
(initialization failure) at
java.lang.J9VMInternals.initialize(J9VMInternals.java:140) at
com.sun.xml.internal.ws.server.SDDocumentImpl.writeTo(SDDocumentImpl.java:266)
at
com.sun.xml.internal.ws.transport.http.HttpAdapter.publishWSDL(HttpAdapter.java:538)
at
com.sun.xml.internal.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:230)
at
com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handleExchange(WSHttpHandler.java:107)
at
com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handle(WSHttpHandler.java:92)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77) at
sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:77) at
com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:80) at
sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:569)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77) at
sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:541) at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:897)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:919)
at java.lang.Thread.run(Thread.java:738)
when accessing this URL on server:
http://localhost:9999/ws/hello?wsdl
I'm a bit surprised I get anything to Domino log because I think this uses JVM http server. I don't understand why it worked first and now it cannot find this class.
How do I publish JAX WS endpoint to Domino Server?
EDIT
I downloaded the JAX WS jars from here:
http://jax-ws.java.net/
and placed the them in \jvm\lib\ext folder. The WSDL URL started to work again! Also the endpoint URL has some information now. I don't know why I had to do this because the functionality should be included in JVM 1.6. Next I will try to use Domino objects in the endpoint code.
Is it possible to make JAX WS to use Domino http server?
thanks,
Panu
JAX-WS is already included in Notes/Domino. I suspect there may have been some instability introduced within your server whilst you were round-tripping during development.
I've created custom providers and consumers within XPages applications c/w SSJS and Custom Java access without issue since 8.5.3 and in 9.0.
Are you past your issue now? (if so, can you close out this question accordingly please :-)

Is Applet jar downloaded by browser or by JVM?

Assume I have below simple applet. I wonder if the http request to get the jar is made by the browser or by jvm. If it is made by jvm, are browser's cookies and sessions sent to server?
<APPLET
CODE="FieldTestF.class"
WIDTH="100%" HEIGHT="90"
ARCHIVE = "FieldTestF.jar"
>
This example uses an applet.
</APPLET>
The applet JAR is downloaded by the JVM. All applets are associated with an instance of a URLClassloader (or a subclass - the sun.applet.AppletClassLoader in Sun JVMs) that is responsible for loading of all classes and resources required by an applet.
Apparently, most of the infrastructure required for loading of class files and resources is available in the Java runtime, and re-using the same would allow the Java plug-in to not worry about accessing browser internals for the most part.
I'll reproduce the salient parts of the OpenJDK codebase here, that performs this activity. You'll find the interesting stuff in the runLoader() method of sun.applet.AppletPanel:
/**
* Load the applet into memory.
* Runs in a seperate (and interruptible) thread from the rest of the
* applet event processing so that it can be gracefully interrupted from
* things like HotJava.
*/
private void runLoader() {
if (status != APPLET_DISPOSE) {
showAppletStatus("notdisposed");
return;
}
dispatchAppletEvent(APPLET_LOADING, null);
// REMIND -- might be cool to visually indicate loading here --
// maybe do animation?
status = APPLET_LOAD;
// Create a class loader
loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
// Load the archives if present.
// REMIND - this probably should be done in a separate thread,
// or at least the additional archives (epll).
String code = getCode();
// setup applet AppContext
// this must be called before loadJarFiles
setupAppletAppContext();
try {
loadJarFiles(loader); // <-- this is what loads the JAR files
applet = createApplet(loader);
...
Also, getting the browser to fetch the resources would complicate matters for the Java security model. This is in part, due to the fact that applets use their own AccessControlContext that has been setup for them. This context has a default set of permissions that are added to it when the applet is being initialized; the set includes the SocketPermission to connect to the server hosting the codebase, or the FilePermission allowing read access to the filesystem containing the codebase. If resource loading were to be done by the browser, then depending on how the plug-in is implemented the checks might simply not be performed leading to a possible break-down of the security model.
You can confirm the resource loading behavior of the JVM by looking at the network traffic, as indicated in the other answer. I'll post the screenshot from Fiddler as confirmation. The process column indicates which OS process is responsible for sending out the request (in this case it happens to be the Java application launcher java.exe). Apologies for the apparent poor quality of the image - you'll need to resize the image or open it in a new window.
I suppose I could have looked it up, but it seemed much more fun to sniff the connection between the browser and the server to find an answer.
It turns out the request is done by the JVM. This is observable because:
The user agent is Mozilla/4.0 ([OS here]) Java/[Java version here] instead of whatever your browser sends;
The applet file request does not originate from the same port the browser requests come from;
The browser does not acknowledge the requests in the request logs & developer tools.
However, the browser seems to pass cookies along to the JVM when it issues the HTTP request, which means your session data should be available.

Categories