GithubHelp home page GithubHelp logo

puniverse / capsule Goto Github PK

View Code? Open in Web Editor NEW
1.1K 1.1K 103.0 6.01 MB

Dead-Simple Packaging and Deployment for JVM Apps

Home Page: http://capsule.io

License: Eclipse Public License 1.0

Java 99.98% Shell 0.02%
deployment jar java jvm packaging

capsule's People

Contributors

aalberti avatar bellinha avatar circlespainter avatar colemanserious avatar dafnap avatar danthegoodman avatar davidmc24 avatar fbaro avatar lookfirst avatar pron avatar tal-m avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

capsule's Issues

Error unpacking capsule

Version 0.6.0 and 0.6.1 throws an error in Windows 8.1 when running capsule java -jar foo.jar

java.lang.RuntimeException: Exception while extracting jar C:\git\foo\target\foo-0.1-SNAPSHOT-indexsvc.jar to app cache directory C:\Users\Johan\AppData\Local\capsule\apps\foo_0.1-SNAPSHOT
    at Capsule.resetAppCache(Capsule.java:688)
    at Capsule.ensureExtractedIfNecessary(Capsule.java:398)
    at Capsule.prepareForLaunch(Capsule.java:387)
    at Capsule.launch(Capsule.java:370)
    at Capsule.main(Capsule.java:190)
Caused by: java.nio.file.DirectoryNotEmptyException: C:\Users\Johan\AppData\Local\capsule\apps\foo_0.1-SNAPSHOT
    at sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:266)
    at sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:103)
    at java.nio.file.Files.delete(Files.java:1123)
    at Capsule.delete(Capsule.java:1661)
    at Capsule.resetAppCache(Capsule.java:685)
    ... 4 more

Deleting the directory does not resolve the problem, downgrading to 0.5.0 however does.

Unable to set CAPSULE_CACHE_DIR env var in capsule manifest

Let me begin by saying that capsule is a great tool, that has many amazing features to streamline java app deployment and startup!

My setup is the following:

The gradle task looks like:

task fatCapsule(type:FatCapsule) {
  applicationClass '######'
  capsuleManifest {
    environmentVariables = [
      'CAPSULE_CACHE_DIR': '######'
    ]
  }
}

The output capsule manifest looks like:

Manifest-Version: 1.0
Main-Class: Capsule
Application-Class: #######
Environment-Variables: CAPSULE_CACHE_DIR=#######

I am working with capsule in a production system, in which it is not possible to write into the process' user home dir. I have tried the following approaches:

  • Set Extract-Capsule to false in the capsule manifest. I have verified that capsule no longer writes all the jars to the cache; however, capsule still creates the dir, which is undesirable. Also, when executing the capsule jar, there's an error that the capsule can't be found.
  • Set the 'Environment-Variables' manifest property to update the CAPSULE_CACHE_DIR. When I looked at the output of ps -ef | grep capsule, the second jvm process spawned is still using the default home dir setting.
  • Make a bash wrapper for my capsule-jar that will manually set the CAPSULE_CACHE_DIR, if it's not set, to avoid deployment overhead. This works; however, I would like to have this without a bash wrapper, for users that will interact with the capsule jar directly.

Wrapping a Capsule using launch4j

I successfully generated and ran a "fat" (fully contained) Capsule.

I am now trying to distribute it as a launch4j executable.

I then get the following error at run time:
CAPSULE EXCEPTION: Not a JAR/ZIP file while processing environment variable LOCALAPPDATA: C:\Users\Olivier\AppData\Local (for stack trace, run with -Dcapsule.log=verbose)

Considering that one of launch4j selling point is "Doesn't extract the jar from the executable", can a Capsule work in this environment?

Regards.

Extraction doesn't create folders

I have some shell scripts packed inside my jar that are extracted at installation time. They seems to break capsule extraction. One day a move to an executable jar might make them unneeded, but for now I still need them.

It seems that when extraction occurs, capsule doesn't try to construct the folders and so java is unable to open the output stream.

I would normally submit a pull request, but I seem to have some gradle and corporate proxy issues that mean I'm unable to build capsule.

My shell scripts are in the dist/ folder inside my jar.

Here is the error log:

$ java -Dcapsule.log=verbose -jar target/myproject-1.0-SNAPSHOT-capsule-thin.jar
CAPSULE: Dependency manager initialized with repositories: [gbl03814 (http://gbl03814.systems.uk.hsbc:8081/nexus/content/groups/all-maven, default, releases)]
CAPSULE: Locking C:\Users\rousdavi\AppData\Local\capsule\apps\myproject-1.0-SNAPSHOT-capsule-thin\.lock
CAPSULE: Extracting C:\sandbox\java\eclipse-workspace\myproject-repo\myproject\myproject\target\myproject-1.0-SNAPSHOT-capsule-thin.jar to app cache directory C:\Users\rousdavi\AppData\Local\capsule\apps\myproject-1.0-SNAPSHOT-capsule-thin
CAPSULE EXCEPTION: Exception while extracting jar C:\sandbox\java\eclipse-workspace\myproject-repo\myproject\myproject\target\myproject-1.0-SNAPSHOT-capsule-thin.jar to app cache directory C:\Users\rousdavi\AppData\Local\capsule\apps\myproject-1.0-SNAPSHOT-capsule-thin
java.lang.RuntimeException: Exception while extracting jar C:\sandbox\java\eclipse-workspace\myproject-repo\myproject\myproject\target\myproject-1.0-SNAPSHOT-capsule-thin.jar to app cache directory C:\Users\rousdavi\AppData\Local\capsule\apps\myproject-1.0-SNAPSHOT-capsule-thin
        at Capsule.extractCapsule(Capsule.java:907)
        at Capsule.ensureExtractedIfNecessary(Capsule.java:544)
        at Capsule.prepareForLaunch(Capsule.java:512)
        at Capsule.prelaunch(Capsule.java:503)
        at Capsule.launch(Capsule.java:455)
        at Capsule.main(Capsule.java:246)
Caused by: java.nio.file.NoSuchFileException: C:\Users\rousdavi\AppData\Local\capsule\apps\myproject-1.0-SNAPSHOT-capsule-thin\dist\encrypt.sh
        at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79)
        at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
        at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
        at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230)
        at java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:430)
        at java.nio.file.Files.newOutputStream(Files.java:170)
        at java.nio.file.Files.copy(Files.java:2841)
        at Capsule.writeFile(Capsule.java:1993)
        at Capsule.extractJar(Capsule.java:1805)
        at Capsule.extractCapsule(Capsule.java:905)
        ... 5 more

can't build project

not able to build the project

pedro@pedro-laptop:~/dev/java/capsule$ gradle compileJava

FAILURE: Build failed with an exception.

* Where:
Build file '/home/pedro/dev/java/capsule/build.gradle' line: 169

* What went wrong:
A problem occurred evaluating root project 'capsule'.
> No such property: sonatypeUsername for class: org.gradle.api.publication.maven.internal.ant.DefaultGroovyMavenDeployer

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 5.975 secs

don't know much of gradle but it seems to be trying to deploy to sonatype repos when I actually only want to build the local jar...

adding build info to the project on github would help...

Capsule trampoline

Make it so really executable capsules would exec rather than fork the capsule's app, and a fork capsule will simply set up things.

Is it possible to set an app default for the cache dir ?

I understand that the cache dir is configurable by env or system parameters and that the default location is the within a user's home directory. What I'd like is the option to set the default cache location to be co-located with the Capsule.

/mycapsule.jar
/lib/{extract/download dependencies here}

It would be rather convenient to set something in the Capsule at build time that preferred this extraction point rather than relying on users to set an environment variable or providing a wrapper script.

Cant run thin jar: Illegal exclusion dependency coordinates

Hey, cool project! It would be truly awesome to get rid of maven shade forever :)

An issue though:
I'm having problems running a thin jar:

CAPSULE: Dependency manager initialized with repositories: [central, (central,, default, releases+snapshots), local (file:/Users/viktor/.m2/repository, default, releases+snapshots)]
CAPSULE: Locking /Users/viktor/.capsule/apps/webservice-0-SNAPSHOT-capsule-thin/.lock
CAPSULE: Extracting /Volumes/case-sensetive/dev/forecast-api/webservice/target/webservice-0-SNAPSHOT-capsule-thin.jar to app cache directory /Users/viktor/.capsule/apps/webservice-0-SNAPSHOT-capsule-thin
CAPSULE: Using JVM: /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre (current)
CAPSULE EXCEPTION: Illegal exclusion dependency coordinates: com.videoplaza.forecast.api:api:0-SNAPSHOT(,org.slf4j:slf4j-log4j12,org.jboss.resteasy:resteasy-jaxrs) (in exclusion )
java.lang.IllegalArgumentException: Illegal exclusion dependency coordinates: com.videoplaza.forecast.api:api:0-SNAPSHOT(,org.slf4j:slf4j-log4j12,org.jboss.resteasy:resteasy-jaxrs) (in exclusion )
    at capsule.DependencyManagerImpl.getExclusions(DependencyManagerImpl.java:283)
    at capsule.DependencyManagerImpl.toDependency(DependencyManagerImpl.java:233)
    at capsule.DependencyManagerImpl.toDependencies(DependencyManagerImpl.java:243)
    at capsule.DependencyManagerImpl.resolveDependencies(DependencyManagerImpl.java:166)
    at Capsule.resolveDependencies(Capsule.java:1354)
    at Capsule.buildClassPath(Capsule.java:856)
    at Capsule.buildJavaProcess(Capsule.java:792)
    at Capsule.buildProcess(Capsule.java:413)
    at Capsule.prepareForLaunch(Capsule.java:392)
    at Capsule.launch(Capsule.java:374)
    at Capsule.main(Capsule.java:194)

I have no idea what the error message means.. But it's hinting to this part of my pom:

   <dependencies>
      <dependency>
         <groupId>com.videoplaza.forecast.api</groupId>
         <artifactId>api</artifactId>
         <version>${project.version}</version>
         <exclusions>
            <exclusion>
               <groupId>org.slf4j</groupId>
               <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
            <exclusion>
               <groupId>org.jboss.resteasy</groupId>
               <artifactId>resteasy-jaxrs</artifactId>
            </exclusion>
         </exclusions>
      </dependency>

(com.videoplaza.forecast.api.api is a sibling project in a multi-module build)

Not sure if relevant, but I'm using christokios maven plugin:

 <plugin>
         <groupId>com.github.christokios</groupId>
         <artifactId>capsule-maven-plugin</artifactId>
         <version>0.7.1</version>
         <executions>
            <execution>
               <phase>package</phase>
               <goals>
                  <goal>capsule</goal>
               </goals>
               <configuration>

                  <!-- REQUIRED -->
                  <appClass>com.videoplaza.forecast.webservice.ForecastApiApplication</appClass>

                  <!-- OPTIONAL -->
                  <outputDir>target/</outputDir>
                  <!--<properties>-->
                     <!--<property>-->
                        <!--<name>propertyName1</name>-->
                        <!--<value>propertyValue1</value>-->
                     <!--</property>-->
                  <!--</properties>-->
                  <buildExec>true</buildExec>
                  <manifest>
                     <!--<property>-->
                        <!--<name>JVM-Args</name>-->
                        <!--<value>-Xmx512m</value>-->
                     <!--</property>-->
                     <property>
                        <name>Repositories</name>
                        <value>central, local</value>
                     </property>
                     <property>
                        <name>Allow-Snapshots</name>
                        <value>true</value>
                     </property>
                     <property>
                        <name>Min-Java-Version</name>
                        <value>1.8.0</value>
                     </property>
                  </manifest>

               </configuration>
            </execution>
         </executions>
      </plugin>

The regular fat jar works just fine.

Any ideas?

Finding the correct AppData folder in Windows is hard

I'm looking into capsule and I wondered how you figured out the path to AppData under Windows.

This is actually a hard problem, because the concept of "userhome" changed a lot during windows-versions. The most reliable way of getting the correct folder is making a library-call using jna.

See this SO-question: https://stackoverflow.com/questions/585534/what-is-the-best-way-to-find-the-users-home-directory-in-java

Here is an implementation I wrote years ago to get the correct application-data folder: https://github.com/fab1an/appkit/blob/master/src/org/appkit/osdependant/OSUtils.java

no support for OpenBSD

Capsule fails with a "unrecognized OS: OpenBSD" when deploying a capsule app to an OpenBSD machine.

I tried getting around this by specifying -Dos.name=Linux but then the NIO package hangs trying to get the filesystem implementation which seems to use hardcoded platform specific implementation classes that are not included in the JVM i am trying to use.

Exception in thread "main" java.lang.AssertionError: java.lang.ClassNotFoundException: sun/nio/fs/LinuxFileSystemProvider
        at sun.nio.fs.DefaultFileSystemProvider$1.run(DefaultFileSystemProvider.java:49)
        at sun.nio.fs.DefaultFileSystemProvider$1.run(DefaultFileSystemProvider.java:43)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.nio.fs.DefaultFileSystemProvider.createProvider(DefaultFileSystemProvider.java:42)
        at sun.nio.fs.DefaultFileSystemProvider.create(DefaultFileSystemProvider.java:70)
        at java.nio.file.FileSystems$DefaultFileSystemHolder.getDefaultProvider(FileSystems.java:108)
        at java.nio.file.FileSystems$DefaultFileSystemHolder.access$000(FileSystems.java:89)
        at java.nio.file.FileSystems$DefaultFileSystemHolder$1.run(FileSystems.java:98)
        at java.nio.file.FileSystems$DefaultFileSystemHolder$1.run(FileSystems.java:96)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.nio.file.FileSystems$DefaultFileSystemHolder.defaultFileSystem(FileSystems.java:95)
        at java.nio.file.FileSystems$DefaultFileSystemHolder.<clinit>(FileSystems.java:90)
        at java.nio.file.FileSystems.getDefault(FileSystems.java:176)
        at java.nio.file.Paths.get(Paths.java:84)
        at Capsule.<clinit>(Capsule.java:243)
Caused by: java.lang.ClassNotFoundException: sun/nio/fs/LinuxFileSystemProvider
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:266)
        at sun.nio.fs.DefaultFileSystemProvider$1.run(DefaultFileSystemProvider.java:47)
        ... 14 more

Capsule processes exit with incorrect status code when run non-interactively

I have a capsule JAR that I'm using for deployment orchestration (interact with load balancer, monitoring, configuration management, etc.) When an error is encountered, the process must exit with a non-zero status code so that the process that called the deployer can react accordingly.

The JAR works fine when called manually, but when called from Bamboo (or, for that matter, with /dev/null piped to stdin), Capsule returns status code 0 without waiting for the process to complete. This results in Bamboo jobs continuing when they should have failed.

Thin capsule mode ignores missing dependancies

I'we made a thin jar using the maven plugin, and try to run it. During the download dependancies phase, I get error messages like these for a few dependencies:

CAPSULE: Downloading: file:/Users/viktor/.m2/repository/com/thoughtworks/xstream/xstream/1.4.2/xstream-1.4.2.jar
CAPSULE: Downloaded: file:/Users/viktor/.m2/repository/com/thoughtworks/xstream/xstream/1.4.2/xstream-1.4.2.jar (471 KB at 530.3 KB/sec)
CAPSULE: Downloading: file:/Users/viktor/.m2/repository/org/hibernate/hibernate-core/3.3.2.GA/hibernate-core-3.3.2.GA.jar
CAPSULE: Transfer failed: capsule.org.eclipse.aether.transfer.ArtifactNotFoundException: Could not find artifact org.hibernate:hibernate-core:jar:3.3.2.GA in local (file:/Users/viktor/.m2/repository)
capsule.org.eclipse.aether.transfer.ArtifactNotFoundException: Could not find artifact org.hibernate:hibernate-core:jar:3.3.2.GA in local (file:/Users/viktor/.m2/repository)
    at capsule.org.eclipse.aether.connector.basic.ArtifactTransportListener.transferFailed(ArtifactTransportListener.java:39)
    at capsule.org.eclipse.aether.connector.basic.BasicRepositoryConnector$TaskRunner.run(BasicRepositoryConnector.java:355)
    at capsule.org.eclipse.aether.util.concurrency.RunnableErrorForwarder$1.run(RunnableErrorForwarder.java:67)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:744)
CAPSULE: Downloading: file:/Users/viktor/.m2/repository/hsqldb/hsqldb/1.8.0.7/hsqldb-1.8.0.7.jar
CAPSULE: Downloaded: file:/Users/viktor/.m2/repository/hsqldb/hsqldb/1.8.0.7/hsqldb-1.8.0.7.jar (629 KB at 707.9 KB/sec)

Then, at run time, I (predictably) get "methodNotFound" errors:

Exception in thread "main" java.lang.NoSuchMethodError: org.hibernate.validator.HibernateValidatorConfiguration.addValidatedValueHandler(Lorg/hibernate/validator/spi/valuehandling/ValidatedValueUnwrapper;)Lorg/hibernate/validator/HibernateValidatorConfiguration;
    at io.dropwizard.setup.Bootstrap.<init>(Bootstrap.java:66)
    at io.dropwizard.Application.run(Application.java:67)
    at com.videoplaza.forecast.webservice.ForecastApiApplication.main(ForecastApiApplication.java:25)

It's probably unwise to keep going after a dependancy has failed to resolve.. Also I would like to hide a bit of the capsule output as it is hard to pick up what is my application, what is capsule, and what went wrong right now.


As for the actual error, I would appreciate any help on that too, obviously :p
The local repository does indeed not contain the jar it's looking for, only a POM. I would assume the right thing to do in that case would be to check maven central too.. Or perhaps, for some reason, some dependancy only wants to see the POM but doesn't need the jar? I have no idea actually.

This is the message I get when starting up:

CAPSULE: Dependency manager initialized with repositories: [central, (central,, default, releases+snapshots), local (file:/Users/viktor/.m2/repository, default, releases+snapshots)]

And my build step:

<!-- BUILD CAPSULES -->
      <plugin>
         <groupId>com.github.christokios</groupId>
         <artifactId>capsule-maven-plugin</artifactId>
         <version>0.8.0-SNAPSHOT</version>
         <executions>
            <execution>
               <phase>package</phase>
               <goals>
                  <goal>capsule</goal>
               </goals>
               <configuration>

                  <!-- REQUIRED -->
                  <appClass>com.videoplaza.forecast.webservice.ForecastApiApplication</appClass>

                  <!-- OPTIONAL -->
                  <outputDir>target/</outputDir>
                  <!--<properties>-->
                     <!--<property>-->
                        <!--<name>propertyName1</name>-->
                        <!--<value>propertyValue1</value>-->
                     <!--</property>-->
                  <!--</properties>-->
                  <buildExec>true</buildExec>
                  <manifest>
                     <!--<property>-->
                        <!--<name>JVM-Args</name>-->
                        <!--<value>-Xmx512m</value>-->
                     <!--</property>-->
                     <property>
                        <name>Repositories</name>
                        <value>central, local</value>
                     </property>
                     <property>
                        <name>Allow-Snapshots</name>
                        <value>true</value>
                     </property>
                     <property>
                        <name>Min-Java-Version</name>
                        <value>1.8.0</value>
                     </property>
                  </manifest>

               </configuration>
            </execution>
         </executions>
      </plugin>

Thankful for your help!

$CAPSULE_DIR value on Windows don't have separator

Hi there. I'd like to try to use Modern Java development workflow as per described here. But unfortunately, when I try to run the capsule that is generated, it returns error.

I found the error. $CAPSULE_DIR variable don't have file separator in Windows:

Exception in thread "main" java.io.FileNotFoundException: File C:UsersjohnAppDataLocalcapsuleappsapidemo.Main_0.1.0\apidemo\apidemo.yml not found

Using Capsule for optional unpacked dependencies

As a feature request, I'd like to be able to specify conditional dependencies as well as use unpacked jar files. Some projects may already have a dependency in the class path, depending on the environment.

This happens often in Hadoop environments, in both Hive and Hadoop the JAR that's been submitted will contain all of its dependencies (via assembly plugin) except for the Hive/Hadoop dependencies, which are provided by the environment.

Essentially, I want a fat class, sans a few dependencies, which are downloaded if/when needed.

Capsule doesn't unpack class files from /WEB-INF/classes

I've constructed a war that looks something like below

foo.war
|-- Capsule.class
`-- WEB-INF
     |-- lib
     `-- classes
          |-- logging.properties
          `-- package/with/classes/SomeClass.class

Looking at the cache directory after running the application WEB-INF/classes only contans logging.properties and neither the directory structure nor classes within.

capsule-0.7.1 / Windows 8.

Would like a way to add dependencies outside of the capsule root

As discussed at https://groups.google.com/forum/#!topic/capsule-user/1kkx8-Y58R0, it would be nice to have a way for caplets to add dependencies outside of the capsule root.

For instance, client libraries in the Hadoop ecosystem require their configuration to be loaded from the classpath. Currently my attempt to write a capsule for this results in:

CAPSULE EXCEPTION: Could not resolve item /etc/hive/conf while processing attribute Dependencies: [/etc/hive/conf]
java.lang.RuntimeException: Could not resolve item /etc/hive/conf
    at Capsule.resolve(Capsule.java:2781)
    at Capsule.resolve(Capsule.java:2813)
    at Capsule.buildClassPath(Capsule.java:1864)
    at Capsule.buildJavaProcess(Capsule.java:1744)
    at Capsule.buildProcess0(Capsule.java:1273)
    at Capsule.buildProcess(Capsule.java:1264)
    at Capsule.buildProcess(Capsule.java:1264)
    at Capsule.buildProcess(Capsule.java:1264)
    at Capsule.prelaunch0(Capsule.java:1237)
    at Capsule.prelaunch(Capsule.java:1232)
    at Capsule.prelaunch(Capsule.java:1232)
    at Capsule.prelaunch(Capsule.java:1232)
    at Capsule.prepareForLaunch(Capsule.java:1146)
    at Capsule.launch(Capsule.java:1091)
    at Capsule.main0(Capsule.java:332)
    at Capsule.main(Capsule.java:311)
Caused by: java.lang.IllegalArgumentException: Path /etc/hive/conf is not local to app cache /home/sam/.capsule/apps/hivelint.HiveLint_0.1.2147483647
    at Capsule.sanitize(Capsule.java:3003)
    at Capsule.resolve(Capsule.java:2768)
    ... 15 more

Multi-module maven projects should include specified sibling modules artifacts in thin jars

In many scenarios, a multi-module maven build will be deployed as a unit (ex. SNAPSHOT builds that share a common version), but are decomposed for "static modularity". In some cases, these artifacts may need special packing themselves (e.g. shade class relocation). For this reason, it would be extremely useful to add the ability to add their primary artifact to the contents of the thin jar.

I need to run my capsuled jar on Java 6

I need to run my capsule'd jar on Java 6, but the capsule jar is compiled with targetCompatibility = '1.7'. Is that actually required? Or will Capsule run with targetCompatibility set to 1.6?

Here's what it looks like when you run a capsuled jar on Java 6:

$ ./my-tool.jar
Exception in thread "main" java.lang.UnsupportedClassVersionError: Capsule : Unsupported major.minor version 51.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Could not find the main class: Capsule. Program will exit.

Need ability to set JVM args on the command line that apply to the Application but not Capsule

For debugging, I need to set the following JVM argument :: -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=9999

However I don't want it to apply to the Capsule exec, but rather only the Application exec. If it applies to both, then the application errors out with "Address already in use"

Possibly something like -Dcapsule.jvm.args=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=9999 and then the jdwp statement is only applied to the Application.

I know I can set JVM-Args in the manifest, but I don't want the debugging port available in production. I just want to set it on the command line as needed.

User JAR file path cannot be added to a custom classpath

maven caplet should allow users to include their own jars to the classpath overriding the attribute method.

Currently the sanitize method does not allow that and raises the following exception:

CAPSULE EXCEPTION: Could not resolve item /Users/pditommaso/workspace/nextflow/gradle/wrapper/gradle-wrapper.jar
java.lang.RuntimeException: Could not resolve item /Users/pditommaso/workspace/nextflow/gradle/wrapper/gradle-wrapper.jar
    at Capsule.resolve(Capsule.java:2781)
    at Capsule.buildClassPath(Capsule.java:1858)
    at Capsule.buildJavaProcess(Capsule.java:1744)
    at Capsule.buildProcess0(Capsule.java:1273)
    at Capsule.buildProcess(Capsule.java:1264)
    at Capsule.buildProcess(Capsule.java:1264)
    at Capsule.buildProcess(Capsule.java:1264)
    at Capsule.prelaunch0(Capsule.java:1237)
    at Capsule.prelaunch(Capsule.java:1232)
    at CapsuleLoader.prelaunch(CapsuleLoader.java:45)
    at Capsule.prepareForLaunch(Capsule.java:1146)
    at Capsule.launch(Capsule.java:1091)
    at Capsule.main0(Capsule.java:332)
    at Capsule.main(Capsule.java:311)
Caused by: java.lang.IllegalArgumentException: Path /Users/pditommaso/workspace/nextflow/gradle/wrapper/gradle-wrapper.jar is not local to app cache /Users/pditommaso/.nextflow/capsule/apps/nextflow_0.13.0-SNAPSHOT
    at Capsule.sanitize(Capsule.java:3003)
    at Capsule.resolve(Capsule.java:2768)
    ... 13 more
Unable to initialize nextflow environment

https://groups.google.com/d/msg/capsule-user/1kkx8-Y58R0/E95C17QL4ZoJ

Running a capsule fat jar after the first time produces stack-blowing recursion

Please see this simple project: https://github.com/chrisfjones/capsule-stackoverflow-test
.. for reproduction.

Essentially, when running a capsule fat jar more than once; an infinite recursion is created between:
at Capsule.buildAppCacheDir(Capsule.java:1558)
at Capsule.getAppCache(Capsule.java:1531)
at Capsule.buildAppCacheDir0(Capsule.java:1576)

In case this is environment specific:

$ mvn -v
Apache Maven 3.2.5 (12a6b3acb947671f09b81f49094c53f426d8cea1; 2014-12-14T09:29:23-08:00)
Maven home: /usr/local/Cellar/maven/3.2.5/libexec
Java version: 1.8.0_25, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.10.1", arch: "x86_64", family: "mac"

Permissions issue when sharing the cache

Based off the conversation from #47, I decided to go with the approach of caching to /tmp; however, in that scenario, users would be sharing the same cache. I noticed that capsule keeps a .lock file, which is world-readable but not world-writable (obviously; just stating the case for completeness). The user who first generates the cache will be both user and group for the entire cache, including the .lock file; however, I noticed that the .lock file was not cleaned up after running the app via capsule.

It looks like all of the files under the main cache dir are world-readable (without umask interfering, of course), so as long as capsule only does reads against the cache, there should not be a problem with the fact that the user/group are both the set to the user who first generated the cache. However, it appears there may be issues in capsule with keeping this .lock file in-sync when the cache is in a shared location.

The main error we are getting for other users is the typical AccessDeniedException when trying to access the .lock file:

CAPSULE EXCEPTION: java.nio.file.AccessDeniedException: /path/to/cache/apps/X/.lock (for stack trace, run with -Dcapsule.log=verbose)

I can run with verbose on, if you think it would add additional info.

Capsule fails to parse some versions of the JRE

Trying to run on the JRE 1.8.0_20-ea:

$ java -version
java version "1.8.0_20-ea"
Java(TM) SE Runtime Environment (build 1.8.0_20-ea-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b12, mixed mode)

It crashes parsing the version.

$ java -Dcapsule.log=verbose -jar ./build/libs/foo.jar
CAPSULE EXCEPTION: For input string: "20-ea"
java.lang.NumberFormatException: For input string: "20-ea"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:580)
    at java.lang.Integer.parseInt(Integer.java:615)
    at Capsule.parseJavaVersion(Capsule.java:1528)
    at Capsule.compareVersions(Capsule.java:1507)
    at Capsule.isMatchingJavaVersion(Capsule.java:1186)
    at Capsule.getJavaHome(Capsule.java:1171)
    at Capsule.<init>(Capsule.java:218)
    at Capsule.newCapsule(Capsule.java:200)
    at Capsule.main(Capsule.java:162)

Java-Agents in manifest attributes yields unexpected errors

I was trying to follow this guide (pt3) and tried to add jolikia as described in pt2 of that guide. However, in that case, the line 'Java-Agents' : "${getDependencies(configurations.jolokia).iterator().next()}=port=7777,host=localhost", causes the capsule to execute /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java [...] -javaagent:/home/user/.capsule/apps/jmodern.web.Main/jolokia-jvm-1.2.3-agent.jar==port=7777,host=localhost [...] jmodern.web.Main

Clearly, this causes the error: /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java [...] -javaagent:/home/user/.capsule/apps/jmodern.web.Main/jolokia-jvm-1.2.3-agent.jar==port=7777,host=localhost [...] jmodern.web.Main, since there is a superfluous = in there.

However, leaving out the 1st = results in an entirely different command, that also won't work because capsule seems to append port to the artifact name (instead of using the jar path), causing this error: java.lang.IllegalArgumentException: Dependency manager not found, and could not locate artifact org.jolokia:jolokia-jvm:1.2.3:agentport in capsule

This is my full build.gradle:

apply plugin: 'java'
apply plugin: 'application'

sourceCompatibility = '1.8'

mainClassName = 'jmodern.web.Main'
version = '0.1.0'

repositories {
    jcenter()
    mavenCentral()
}

configurations {
    markdownDoclet
    jolokia
    capsule

    all*.exclude group: "org.apache.logging.log4j", module: "*"
}

dependencies {
    compile 'com.google.guava:guava:18.0'
    compile 'org.slf4j:slf4j-api:1.7.12'
    compile 'org.projectlombok:lombok:1.16.2'
    compile 'io.dropwizard:dropwizard-core:0.8.1'
    compile 'io.dropwizard.metrics:metrics-core:3.1.1'

    testCompile 'junit:junit:4.12'
    testCompile 'org.hamcrest:hamcrest-all:1.3'

    //runtime 'org.slf4j:slf4j-jdk14:1.7.12' // SLF4J binding for java.util.logging
    runtime 'ch.qos.logback:logback-classic:1.1.3'

    markdownDoclet 'ch.raffael.pegdown-doclet:pegdown-doclet:1.1.1'
    jolokia "org.jolokia:jolokia-jvm:1.2.3:agent"
    capsule "co.paralleluniverse:capsule:0.10.0"
}

run {
    jvmArgs "-javaagent:${configurations.jolokia.iterator().next()}=port=7777,host=localhost"

    systemProperty "com.sun.management.jmxremote", ""
    systemProperty "com.sun.management.jmxremote.port", "9999"
    systemProperty "com.sun.management.jmxremote.authenticate", "false"
    systemProperty "com.sun.management.jmxremote.ssl", "false"

    systemProperty "dropwizard.config", "build/resources/main/jmodern-web.yml"
}

javadoc.options {
    docletpath = configurations.markdownDoclet.files.asType(List)
    doclet = "ch.raffael.doclets.pegdown.PegdownDoclet"
    addStringOption("parse-timeout", "10")
}

task capsule(type: Jar, dependsOn: jar) {
    archiveName = "jmodern-web.jar"

    from jar // embed our application jar
     // embed dependencies
    from { configurations.runtime }
    from { configurations.jolokia }
    // embed resources
    from { sourceSets.main.resources }

    from(configurations.capsule.collect { zipTree(it) }) { include 'Capsule.class' } // we just need the single Capsule class

    manifest {
        attributes(
            'Main-Class'  : 'Capsule',
            'Application-Class' : mainClassName,
            'Min-Java-Version' : '1.8.0',
            'JVM-Args' : run.jvmArgs.join(' '), // copy JVM args from the run task
            'System-Properties' : (run.systemProperties + ["dropwizard.config": '$CAPSULE_DIR/jmodern-web.yml']).collect { k,v -> "$k=$v" }.join(' '), // copy system properties (+ jmodern config)
            'Java-Agents' : "${getDependencies(configurations.jolokia).iterator().next()}=port=7777,host=localhost",
        )
    }
}

// converts Gradle dependencies to Capsule dependencies
def getDependencies(config) {
    return config.getAllDependencies().collect {
        def res = it.group + ':' + it.name + ':' + it.version +
            (!it.artifacts.isEmpty() ? ':' + it.artifacts.iterator().next().classifier : '')
        if(!it.excludeRules.isEmpty()) {
            res += "(" + it.excludeRules.collect { it.group + ':' + it.module }.join(',') + ")"
        }
        return res
    }
}

null while processing system property java.home

Getting this error after upgrading Capsule to version 0.10.0:

CAPSULE: Launching app example.FooBarService_0.0.1
CAPSULE: Locking /home/example/.capsule/apps/example.FooBarService_0.0.1/.lock
CAPSULE: Extracting /usr/share/example-service/lib/example-service.jar to app cache directory /home/example/.capsule/apps/example.FooBarService_0.0.1
CAPSULE: Error parsing Java version 1.8.0_31
CAPSULE: Unocking /home/example/.capsule/apps/example.FooBarService_0.0.1/.lock
CAPSULE EXCEPTION: null while processing system property java.home: /usr/lib/jvm/java-8-oracle/jre
java.lang.NullPointerException
    at Capsule.getJavaHomes(Capsule.java:2998)
    at Capsule.findJavaHome(Capsule.java:2125)
    at Capsule.chooseJavaHome0(Capsule.java:2107)
    at Capsule.chooseJavaHome(Capsule.java:2098)
    at Capsule.getJavaHome(Capsule.java:2085)
    at Capsule.getJavaExecutable0(Capsule.java:1633)
    at Capsule.getJavaExecutable(Capsule.java:1625)
    at Capsule.buildJavaProcess(Capsule.java:1579)
    at Capsule.buildProcess0(Capsule.java:1153)
    at Capsule.buildProcess(Capsule.java:1144)
    at Capsule.prelaunch0(Capsule.java:1122)
    at Capsule.prelaunch(Capsule.java:1118)
    at Capsule.prepareForLaunch(Capsule.java:1033)
    at Capsule.launch(Capsule.java:974)
    at Capsule.main0(Capsule.java:296)
    at Capsule.main(Capsule.java:275)

JAVA_HOME is set:

$ echo $JAVA_HOME
/usr/lib/jvm/java-8-oracle

Here's the MANIFEST.MF for this application:

Manifest-Version: 1.0
Main-Class: Capsule
Application-Class: example.FooBarService
Application-Version: 0.0.1
Min-Java-Version: 1.8
JVM-Args:
System-Properties: example.config=/etc/example-service/example.yml

NullPointerException on windows

The method windowsJavaHomesHeuristics calls the method getJavaHomes. The method getJavaHomes can return null. When it does, then windowsJavaHomesHeuristics will try to call allHomes.putAll with this null value, which results in a NullPointerException (in HashMap.putMapEntries, which calls m.entrySet()).

The solution I tried is simple: check the result of getJavaHomes and only call putAll when the result is not null.

Terminating app on Windows behaves differently than Linux

ctrl-c on Linux gracefully terminates both JVMs and my app.
ctrl-c on Windows CMD prompt terminates both JVMs but not gracefully AFAICS.

My app has a JVM shutdown hook that produces many log lines. Intermittently I see the first log entry so perhaps Capsule shutdown is too aggressive? My app might be shutting down gracefully but silently, not sure.

As a lesser issue, ctrl-c on Windows Babun/zsh/Cygwin terminates the Capsule JVM but leaves the app JVM orphaned & running.

ArrayIndexOutOfBoundsException upgrading to 0.10.0 version

Upgrading from 0.9.0 to 0.10.0 I'm getting the following exception in some environments, though I'm unable to replicate the exact problem.

CAPSULE: Dependency manager repositories: [central (https://repo1.maven.org/maven2/, default, releases)]
CAPSULE: Launching app nextflow-one_0.12.2
CAPSULE: Locking /users/rg/sdjebali/.nextflow/capsule/apps/nextflow-one_0.12.2/.lock
CAPSULE: Extracting /nfs/users/rg/sdjebali/.nextflow/framework/0.12.2/nextflow-0.12.2-one.jar to app cache directory /users/rg/sdjebali/.nextflow/capsule/apps/nextflow-one_0.12.2
CAPSULE: Using JVM: /usr/java/jdk1.7.0_60/jre
CAPSULE: Unocking /users/rg/sdjebali/.nextflow/capsule/apps/nextflow-one_0.12.2/.lock
CAPSULE EXCEPTION: 0 while processing attribute Library-Path-A: null
java.lang.ArrayIndexOutOfBoundsException: 0
    at sun.nio.fs.UnixPath.normalize(UnixPath.java:508)
    at Capsule.toAbsolutePath(Capsule.java:2669)
    at Capsule.processOutgoingPath0(Capsule.java:2609)
    at Capsule.processOutgoingPath(Capsule.java:2603)
    at Capsule.processOutgoingPath(Capsule.java:2617)
    at Capsule.compileClassPath(Capsule.java:1653)
    at Capsule.buildSystemProperties0(Capsule.java:1827)
    at Capsule.buildSystemProperties(Capsule.java:1815)
    at Capsule.buildSystemProperties(Capsule.java:1800)
    at Capsule.buildJavaProcess(Capsule.java:1582)
    at Capsule.buildProcess0(Capsule.java:1153)
    at Capsule.buildProcess(Capsule.java:1144)
    at Capsule.prelaunch0(Capsule.java:1122)
    at Capsule.prelaunch(Capsule.java:1118)
    at CapsuleLoader.prelaunch(CapsuleLoader.java:46)
    at Capsule.prepareForLaunch(Capsule.java:1033)
    at Capsule.launch(Capsule.java:974)
    at Capsule.main0(Capsule.java:296)
    at Capsule.main(Capsule.java:275)

Capsule uses wrong jvm

Capsule used the JRE when the JDK is required which is verified when explicitly setting -Dcapsule.java.home.

The output of java -Dcapsule.jvms -jar foo.jar is

CAPSULE: No detected Java installations
CAPSULE: selected null

Below are the used manifestEntries configured by JDK-Required as per by the docs

<manifestEntries>
    <Application-Name>backend-app</Application-Name>
    <Application-Class>com.foo.capsule.Main</Application-Class>
    <Min-Java-Version>1.6.0</Min-Java-Version>
    <JVM-Args>-Xms512m -Xmx512m -XX:MaxPermSize=128m</JVM-Args>
    <System-Properties>foo.home=${project.build.directory}</System-Properties>
    <Java-Agents>co.paralleluniverse:quasar-core:0.6.0</Java-Agents>
    <JDK-Required>true</JDK-Required>
</manifestEntries>

JDK and JRE are available the following locations respectively.

C:\Program Files (x86)\Java\jre7
C:\Program Files\Java\jre7
C:\Program Files\Java\jdk1.7.0_45

OS: Windows 8.

NullPointerException when listing JVMs

Using 1.0-rc1:

$ java -Dcapsule.log=verbose -Dcapsule.jvms -jar build/libs/hive-cleanup-0.1.2147483647-capsule.jar 
CAPSULE: Jar: /scratch/hive-cleanup/build/libs/hive-cleanup-0.1.2147483647-capsule.jar
CAPSULE: Platform: linux
CAPSULE: Initializing app ID
CAPSULE: Initialized app ID: hivelint.HiveLint_0.1.2147483647
CAPSULE EXCEPTION: null while processing system property java.home: /usr/lib/jvm/jdk-8-oracle-x64/jre
java.lang.NullPointerException
    at Capsule.getJavaHomes(Capsule.java:3404)
    at Capsule.printJVMs(Capsule.java:987)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at Capsule.runActions(Capsule.java:503)
    at Capsule.main0(Capsule.java:329)
    at Capsule.main(Capsule.java:311)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.