I have written custom clojure functions that I want to use in my riemann configuration. I am using leiningen to build jar file (with dependencies) containing my functions. What is the right way to include this jar file in the classpath when starting riemann ?
I have only found this way. I'm not sure whether this is the right way :
java -cp "/path/to/my/custom.jar:/path/to/riemann-0.2.6/lib/riemann.jar" riemann.bin /path/to/riemann-0.2.6/etc/riemann.config
Related
I work on a Java project, whose tests I want to convert to scala. I saw that it might be more convenient to package the entire project jar with sbt, rather than with maven.
However, I currently have a single pom.xml file, that creates a jar with all dependencies inside ("fat jar") using maven shade plugin, and runs the tests. This is achieved via the "mvn package" command.
With sbt, I saw that 2-3 files are needed just for the fat jar - build.sbt, assembly.sbt, possibly plugins.sbt.
Is there some way by which I can have a single xxx.sbt file, and run one / several sbt commands, to get the same effect?
No, you need at least two files: project/plugins.sbt with the
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.9")
line and build.sbt with the assembly settings. You can merge the *.sbt files in the root directory, sbt reads them all regardless of the name anyway. But the files in the project/ directory are different. You can read more about it in https://www.scala-sbt.org/1.x/docs/Organizing-Build.html
I have a project that is using spring boot and when is build it generates a jar containing all dependencies jars.
I want to obfuscate this jar, but after obfuscation when I try to run the jar I get:
java.lang.IllegalStateException: Unable to open nested entry 'lib/h2-1.4.185.jar'. It has been compressed and nested jar files must be stored without compression. Please check the mechanism used to create your executable jar file
at org.springframework.boot.loader.jar.JarFile.createJarFileFromFileEntry(JarFile.java:378)
at org.springframework.boot.loader.jar.JarFile.createJarFileFromEntry(JarFile.java:355)
at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:341)
at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(JarFileArchive.java:108)
at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchives(JarFileArchive.java:92)
at org.springframework.boot.loader.ExecutableArchiveLauncher.getClassPathArchives(ExecutableArchiveLauncher.java:74)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:60)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:45)
I tried to find what is the issue and for that I create a config file only with:
-injars MyJar-orig.jar
-outjars MyJar.jar
-libraryjars <java.home>/lib/jce.jar
-libraryjars <java.home>/lib/rt.jar(java/**,javax/**)
-libraryjars '..\..\resources\proguard5.0\references\log4j-1.2.17.jar'
-dontobfuscate
-dontshrink
-dontoptimize
I was expected to get the original jar, but I am getting a jar that is smaller and all the classes have different size (smaller in general).
What is proguard doing in this case?
Any idea how I can solve my issue?
please have a look at the '-keepattributes' parameter. When using the Proguard GUI, under the 'Obfuscation' tab there is an option for this. Clicking this solved my problem which was similar/ the same as yours.
When using leiningen to build Clojure applications, how can certain dependencies be excluded from being included in the JAR file when using lein uberjar?
Use the provided entry for the leiningen profile.
:profiles {:dev {:dependencies [[ring-mock "0.1.5"]
[prismatic/dommy "0.1.3"]
[org.bouncycastle/bcprov-jdk15on "1.50"]]}
:provided {:dependencies [[org.bouncycastle/bcprov-jdk15on "1.50"]]}}
One common use case is bouncycastle that needs to be excluded from the signed JAR and provided externally using its own jar file in runtime.
Similar to what Guillermo suggested modify your project's :profiles to include something along the lines of:
:provided {:dependencies [[org.bouncycastle/bcprov-jdk15on "1.50"]
[org.bouncycastle/bcpg-jdk15on "1.50"]]}
(The specific versions may vary.)
Trouble is that if you use a Clojure wrapper library (such as clj-pgp or thi.ng/crypto), it forces inclusion of the jar in the uberjar, breaking the process.
My solution was to fork the library and push it to clojars after modifying its project.clj to uses provided dependencies.
More details here: http://side-effects-bang.blogspot.com/2015/02/deploying-uberjars-that-use-bouncy.html
In the project.clj under :dependencies you can add exclusions for specific jars like this:
[test/test-jar "1.0" :exclusions [sample-exclusion/test-exclusions]]
I'm writing a library which depends on code (let's call it foo.jar) which is only available as a binary jar. As is standard, I'm putting this in the lib/ directory so SBT will treat is as an unmanaged dependency. This is fine so far.
However, since this is a library, I'd like to be able to publish it so that other projects which depend on it to also have access to the unmanaged code in foo.jar without having to manually locate it. I originally thought I could use a fat jar plugin such as SBT Assembly to create a jar with the dependencies, but that doesn't affect what is actually published using sbt publish-local – it only creates a fat jar when you run sbt assembly. Is there some standard simple way to handle this? It seems like a bad idea for every library which uses unmanaged dependencies to break when used by other projects downstream so I wonder if I'm missing something obvious.
I don't know if that's a good use of sbt-assembly, since other libraries could depend on a different version of foo.jar etc.
One way to work around it is to publish foo.jar in a Maven repository yourself. Some people in Scala and/or sbt community have been talking about bintray. It's still in beta, but looks promising if you want some jars published.
You might be able to get the result you want by manipulating the mappings in (Compile, packageBin) to include the files you want your packaged jar to have (publish uses the output from packageBin). This technique will allow you to include absolutely any file you want within the jar. The official sbt doc is here: http://www.scala-sbt.org/0.12.3/docs/Howto/package.html#contents
As an example, consider the common case of including a .properties file within your jar. Lets say you need to include "messages.properties" under the path "com/bigco/messages.properties" in your packaged jar. And lets say that this file is under src/main/scala/ ... You can add the following to your build.sbt:
mappings in (Compile, packageBin) <+= baseDirectory map { base =>
(base / "src" / "main" / "scala" / "com" / "bigco" / "messages.properties") -> "com/bigco/messages.properties"
}
To attempt to answer your original question, you could unzip foo.jar and add each one of the class files within to the packaged jar, according to their correct package paths. So something similar to
mappings in (Compile, packageBin) <+= baseDirectory map { base =>
(base / path / to / unzipped / file.class) -> "path.to.unzipped.file.class"
...
}
Or you might be able to get away with simply including foo.jar at the root of the packaged jar like so:
mappings in (Compile, packageBin) <+= baseDirectory map { base =>
(base / "lib" / "foo.jar") -> "foo.jar"
}
I created simple Java Servlet: WelcomeServlet.java.
Than, I tried compile this file via:
javac WelcomeServlet.java
In result I see compile error:
package javax.servlet doesn't exit
I try find solution for this error with Google. And I find first part of answer: java compiler doesnt see servlet-api.jar file.
I know, that Apache Tomcat in it lib folder contains servlet-api.jar file.
So, I have this file, but where I must copy this file??
I try different folders:
echo %JAVA_HOME%
C:\Program Files\Java\jdk1.6.0_26
%PATH% contains this line: C:\Program Files\Java\jdk1.6.0_26\bin
So, I copy in:
%JAVA_HOME%\bin
%JAVA_HOME%\lib
%JAVA_HOME%\jre\lib
And in result same error.
And only after I copy servlet-api.jar in directory:
%JAVA_HOME%\jre\lib\ext
compilation complite sucessful.
My question: Why? Why I must copy in folder %JAVA_HOME%\jre\lib\ext ??
Where This moment describe in documentation?
And other question we have some official docs or specifications that describe folder structure for jdk folder??
You'll need to specify the directory or directories you want the compiler to search by using the -classpath command line option when running javac. The reason the compiler found your .jar in %JAVA_HOME%\jre\lib\ext is because it searches the extension directories by default.
This is for Java 1.5, but I believe it is more or less still correct:
http://docs.oracle.com/javase/1.5.0/docs/tooldocs/findingclasses.html
The link Shaun provides is a more complete answer. But in short, using the classpath is the best way to introduce 3rd party or external (to the JDK/JRE) libraries. The classpath is a concept much like the %PATH% or the $PATH variables, but specifies locations for java to use for lookup rather than the shell to use for lookup of executables.
The classpath provides the java compiler or java virtual machine a list of items to use when searching for resources. This "path" may include directories or files. It will typically include jar files and sometimes locations of configuration files. Many Java based lookup schemes for files configuration or otherwise use some variant of what is accomplished by [Class#getResourceAsStream()][1]'s use of walking the Classpath.
I have rarely seen an incident where putting a jar file in the lib/ext location was preferred to utilizing the Classpath.
The classpath is typically an environment variable (%CLASSPATH% or $CLASSPATH) or specified on the command line when running java or javac (e.g. -cp or -classpath see the help from the executable you are running).
Build tools such as Ant and Maven will also provide abstractions to defining the list of jars to be utilized by your applications and are highly recommended to be used for any length of repetitive change code, build, test, run cycles.