xLeitix / jcloudscale

Public source code repository for the JCloudScale project
Apache License 2.0
9 stars 2 forks source link

Classpath of JAR-Manifest not taken into account when forking #14

Open 8191 opened 10 years ago

8191 commented 10 years ago

When JCS forks a Java process (e.g. in at.ac.tuwien.infosys.jcloudscale.vm.localVm.LocalVM#launchHost), the classpath "injected" by a JAR manifest is not taken into account. This leads to the problem, that the JCS class files (and other libraries) are not found by the forked process and leads to a JCloudScaleException.

In this example I execute a JAR file containing only my JCS application and load JCS into the classpath by specifying Class-Path: jcloudscale.core-0.4.4.jar in the META-INF/MANIFEST.MF file. When the scaling policy decides to scale up, the exception is thrown:

Error: Could not find or load main class at.ac.tuwien.infosys.jcloudscale.server.JCloudScaleServerRunner
at.ac.tuwien.infosys.jcloudscale.exception.JCloudScaleException: Scaling policy "selectHost" method invocation thrown an exception: at.ac.tuwien.infosys.jcloudscale.exception.ScalingException: JVM failed to launch. Launch Line:
'/usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java -cp jcloudscale.genetics.jar at.ac.tuwien.infosys.jcloudscale.server.JCloudScaleServerRunner'
from folder '/tmp'. Exit code 1
        at at.ac.tuwien.infosys.jcloudscale.management.CloudManager.createNewInstance(CloudManager.java:117)
        at at.ac.tuwien.infosys.jcloudscale.api.CloudObjects.create(CloudObjects.java:106)
        at at.ac.tuwien.infosys.jcloudscale.aspects.CloudObjectAspect.deployCloudObject(CloudObjectAspect.java:93)
        at at.ac.tuwien.infosys.jcloudscale.aspects.CloudObjectAspect.createNewCloudObject(CloudObjectAspect.java:56)
        at at.conf.jcs.genetics.computation.GeneticsComputationImpl.getInstance(GeneticsComputationImpl.java:47)
...
rstzab commented 10 years ago

By default, if you did not change classpath in local platform configuration, JCloudScale uses classpath of your application (using java.class.path system property). If you're not satisfied with this behavior, you can change it by specifying correct classpath using either setClasspath or withClasspath methods of LocalCloudPlatformConfiguration class. (e.g., new JCloudScaleConfigurationBuilder(new LocalCloudPlatformConfiguration().withClasspath(<your custom classpath here>));)

However, in your case, I think that the issue is slightly different. as it is discussed on this page, classpath specified in manifest of your jar (jcloudscale.genetics.jar) should be taken into account by JVM automatically, without any efforts from JCloudScale if jcloudscale.genetics.jar is specified in -cp argument of JVM. However, I'm afraid you did not consider another thing that is clearly stated in the exception message: in order to ensure your cloud objects do not depend on the current folder (as it definitely will be different on remote server), by default, new instances of JCloudScale servers in local environment are started in temp directory. (Remember, local mode is mainly for app development and testing).

However, there is no jcloudscale.genetics.jar in temp directory and, even if there is one, jars in Class-Path property from MANIFEST.MF are usually specified by relevant path to your main jar file location. Therefore, I'd recommend you first to try specifying explicitly that you want to start servers from your directory (using setStartupDirectory or withStartupDirectory methods). Otherwise, just consider specifying classpath correctly.

If you are not satisfied with this answer or I did not understand you, please tell explicitly what I got wrong and what do you expect JCloudScale to do in your particular case.

If you understand application behavior now and you don't see any way to improve it, please, close the issue.

8191 commented 10 years ago

I understand. So the problem is not, that the classpath is not correct, but that the files referenced in the classpath do not exist in the new destination. What exactly does JCS transfer to the new location (either locally or to newly deployed hosts), are all files referenced by the java.class.path property transferred?

Maybe you could change this to a feature request, that JCS transfers all files in the classpath (even classpath extensions by manifest Class-Path option) to the new location?

rstzab commented 10 years ago

Well, JCloudScale is not transferring anything to the new location, that's why everything is missing in temp directory.

The idea of local configuration is to simulate remote execution and there's nothing available at the remote hosts. Therefore, we don't plan to transfer everything from classpath to some other location.

So, the problem is that classpath is not correct for the server location, which is temp directory by default. Therefore, you should either configure classpath or server startup directory in order to make it work.

Currently we are considering to change default server classpath resolution algorithm, but it's still an idea collection phase and we don't have any particular approach in mind. Thus, if you have any offers, be free to tell us. The main goal is to get the same startup classpath as JCloudScale host in EC2 has: JCloudScale dependencies only.