Liferay Uber Module: package does not exist - liferay

I wrote a Liferay 7 module that uses org.apache.http.client.methods.HttpPost.
The needed OSGi components are:
mvn:org.apache.httpcomponents/httpclient-osgi/4.5.3
mvn:org.apache.httpcomponents/httpcore-osgi/4.4.6
Uber Module
Now I am trying a build an Uber Module containing these JARs plus my code, per Option 3 - Make An Uber Module.
So, I manually downloaded the two JARs to my project, then added this to my build.gradle:
runtime group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.3'
runtime group: 'org.apache.httpcomponents', name: 'httpcore', version: '4.4.6'
... and this to my bnd.bnd:
Include-Resource: #httpclient-osgi-4.5.3.jar
Include-Resource: #httpcore-osgi-4.4.6.jar
Problem
When I try to compile, at the compileJava step I immediately get:
error: package org.apache.http does not exist
Adding compileOnly groups in addition to the runtime groups in build.gradle seems to solve the problem, but is it the right thing to do?

you may wanna read this :
Embed thirdparty JAR using BND
tim mentioned there, that you additionally need to add the embedded jar to the bundle class path

Related

Adding KML Library JAK

How do I add a the JAK Library to my java project so I can use it?
I Dont understand how to I acctually make it useable in my Java Porject if it is on Gittub and I dont see the Jar Files.
Can Anyone please help me with a little guidance? I've checked online and 0 videos about it so All I can ask is help from you guys.
Adding jar dependencies to a Java project depends on what build tools are used (e.g. Maven, Gradle, Ant, etc.). If you're using an IDE, the project can be created around the build artifact (pom.xml for Maven projects, build.gradle for Gradle, etc.) or explicitly add jar files to the CLASSPATH for that project.
If you have a Maven project, add this dependency to your pom.xml file:
<dependency>
<groupId>de.micromata.jak</groupId>
<artifactId>JavaAPIforKml</artifactId>
<version>2.2.1</version>
</dependency>
For Gradle project, add this to your build.gradle file:
dependencies {
compile group: 'de.micromata.jak', name: 'JavaAPIforKml', version: '2.2.1'
//...
}
Alternatively, you can manually download the jars from the official dev.java.net Maven 2 repository. Note that JAK depends on JAXB libraries so you will need them also. Review the POM for JAK for details.

Basic resources not available in Liferay 7?

I've been transitioning a portlet from Liferay 6.2 to a bundle for Liferay 7. When I deploy it, it can't load, because of a missing resource:
$ blade sh diag 1084
diag 1084
org.mycompany.caasd.portal-ldap-sync [1084]
Unresolved requirement: Import-Package: com.liferay.portal.kernel.service;
version="[1.20.0,2.0.0)"
When I use Felix Gogo shell to see what's available, I don't see any kernel bundles. Is that a bundle I should be expecting to be installed, install myself, include in my bundle, or am I just not thinking about this the right way?
The com.liferay.portal.kernel version for CE GA4 is 2.32.1. So if you were developing for CEGA4, with a gradle project, you'd configure the dependency in your project's build.gradle like this:
dependencies {
compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel", version: "2.32.1"
}
You can find this by looking in the portal-kernel.jar file's MANIFEST/MANIFEST.MF or if you have the liferay src for your version, in any of its own modules build.gradle files. In my tomcat bundle, the portal-kernel.jar if in tomcat/lib/ext.
Unless I've misunderstood your question, that should get you what you want.
See the docs here for more information
When you build your bundle, bnd will either
inspect your classpath and detect the package versions for you
use whatever versions you manually provide in Import-Package
In your case, it seams it somehow detected that the version of com.liferay.portal.kernel.service package is 1.20.0. It therefore generated the range "equal to or greater than current version but lower than next major version" which in your case is expressed as [1.20.0,2.0.0). That may have been because you had old jar on claspath or behacause you had wrong Import-Package statement.
This may compile just fine as long as you are nor using functionality that was added/changed in the newer version. At runtime though, the actual package version is higher (something like 2.32.1) and therefore it does not meet your requirement. As OSGi runtime can not resolve your bundle requirement, the bundle is left in "istalled" state!
To solve that you have two options:
install your bundle on older Liferay version (where com.liferay.portal.kernel.service package is between 1.20.0 and 2.0.0)
recompile your bundle making sure the classpath contains only those jars in which com.liferay.portal.kernel.service package has version that will generate a version range in which you runtime package version fits.

Groovy: How does #Grab inclusion differ from classpath inclusion?

1. Generally, how is #Grape/#Grab inclusion different than classpath inclusion?
2. Specifically, what might cause the following behavior difference?
I've got a requirement on xpp3 which I express as:
// TestScript.groovy
#Grab(group='xpp3', module='xpp3', version='1.1.3.4.O')
import org.xmlpull.v1.XmlPullParserFactory;
println "Created: " + XmlPullParserFactory.newInstance()
Running $ groovy TestScript.groovy fails with
Caught: org.xmlpull.v1.XmlPullParserException: caused by: org.xmlpull.v1.XmlPullParserException:
If, however, I manually add the .jar fetched by Grape to my Groovy classpath:
$ groovy -cp ~/.groovy/grapes/xpp3/xpp3/jars/xpp3-1.1.3.4.O.jar \
TestScript.groovy
... then everything works.
Grab uses ivy to fetch the specified library (plus all of its dependencies) from the maven core repository. It then adds these downloaded libraries to the classpath of the loader that's running the current script.
Adding the jar to the classpath just adds the specified jar to the system classpath.
As there are no dependencies in this example, it's probably a requirement that the library needs to be loaded by the system classloader.
To check this, try adding
#GrabConfig(systemClassLoader= true)
#Grab(group='xpp3', module='xpp3', version='1.1.3.4.O')
Instead of the one line Grab you currently have

Adding module library to android studio via gradle

I am trying to add ViewPageIndicator library by Jake Wharton to my project's module. I know how to do this with a jar file but since this is a module I am not sure how to add it to the build.gradle file.
This is what my current structure looks like
ExampleProject (Root module)
|
------> Example (main module that needs the library)
|
------> PageIndicatorLibrary
Since this was marked as a popular question. In the hopes that this helps others as well I am posting an alternative answer.
If you import ViewPagerIndicator as a module and not a library. You can compile the project and add is as part of the dependency in the build.gradle file by adding the following to the dependencies section.
dependencies {
compile project(':ViewPagerIndicator')
}
Add something like this in your build.gradle
repositories {
mavenCentral()
}
dependencies {
compile 'com.viewpagerindicator:library:2.4.1'
compile 'com.google.android:support-v4:r7' //transitive dependency of viewpagerindicator
}
From the viewPageIndicator project page :
This project depends on the ViewPager class which is available in the Android Support Library or ActionBarSherlock. Details for including one of those libraries is available on their respecitve web sites.
That's why I added the support lib in the dependencies (you may need another version)

how to export a executable jar in gradle, and this jar can run as it include reference libraries

how to export a executable jar in gradle, and this jar can run as it include reference libraries.
build.gradle
apply plugin: 'java'
manifest.mainAttributes("Main-Class" : "com.botwave.analysis.LogAnalyzer")
repositories {
mavenCentral()
}
dependencies {
compile (
'commons-codec:commons-codec:1.6',
'commons-logging:commons-logging:1.1.1',
'org.apache.httpcomponents:httpclient:4.2.1',
'org.apache.httpcomponents:httpclient:4.2.1',
'org.apache.httpcomponents:httpcore:4.2.1',
'org.apache.httpcomponents:httpmime:4.2.1',
'ch.qos.logback:logback-classic:1.0.6',
'ch.qos.logback:logback-core:1.0.6',
'org.slf4j:slf4j-api:1.6.0',
'junit:junit:4.+'
)
}
after i run : gradle build
it create the build folder, and i run the jar in build/libs/XXX.jar:
java -jar build/libs/XXX.jar
here is a execution says :
Exception in thread "main" java.lang.NoClassDefFoundError: ch/qos/logback/core/joran/spi/JoranException
how can i run it with the reference libraries?
You can achieve it with Gradle application plugin
Hopefully this helps someone (as I unfortunately spent quite some time trying to find the solution). Here's the solution that worked for me for creating an executable JAR. I'm embedding Jetty in the main method, Jetty 9 to be specific and using Gradle 2.1.
Include the following code into your build.gradle file (if a subproject is the "main" project that the jar needs to be built from, then add it to the subproject which should start like this project(':') { insert the code somewhere here, after dependencies.}.
Also, you need to add the plugin java for this to work: apply plugin: 'java' .
My jar task looks as follows:
apply plugin: 'java'
jar {
archiveName = "yourjar.jar"
from {
configurations.runtime.collect {
it.isDirectory() ? it : zipTree(it)
}
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes 'Main-Class': 'your.package.name.Mainclassname'
}
exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
}
And then you can execute your yourjar.jar via the commandline:
java -jar yourjar.jar
The META-INF/.RSA, META-INF/.SF and META-INF/*.DSA have to be excluded for it to work. Otherwise a SecurityException gets thrown.
The problem seems to lie with embedded Jetty, as Jetty moved to Eclipse and now is signing their JARs, which I read becomes problematic when other, unsigned JARs want to load the signed ones. Please feel free to educate me if I am wrong in this, that's just what I read.
The JARs that the project depends on are defined in the dependencies as follows:
dependencies {
// add the subprojects / modules that this depends on
compile project(':subproject-1')
compile project(':subproject-2')
compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '9.2.6.v20141205'
compile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '9.2.6.v20141205'
compile group: 'org.eclipse.jetty', name: 'jetty-http', version: '9.2.6.v20141205'
}
EDIT: Before, instead of just
configurations.runtime.collect{...}
i had
configurations.runtime.asFileTree.files.collect{...}
This caused strange behaviour in a larger project in clean build. When running the jar after executing gradle clean build for the first time (after manually cleaning the build directory), it would throw a NoClassDefFoundException (in our project with many subprojects), but running the jar after executing gradle clean build a second time (without emptying the build directory manually), for some reason it had all dependencies. This didn't happen if asFileTree.files was left out.
Also I should note, all compile dependencies are included in runtime, however not all runtime are included in compile. So if you are just using compile
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
Then be sure to remember that if there is a NoClassDefFoundException thrown, some class isn't found at runtime, which means you should also include this:
configurations.runtime.collect {
it.isDirectory() ? it : zipTree(it)
}
Quick answer
Add the following to your build.gradle:
apply plugin: 'application'
mainClassName = 'org.example.app.MainClass'
jar {
manifest {
attributes 'Main-Class': mainClassName,
'Class-Path': configurations.runtime.files.collect {"$it.name"}.join(' ')
}
}
From the project directory, run gradle installDist
Run java -jar build/install/<appname>/lib/<appname>.jar
I recommend adding the app version to your build.gradle as well, but it's not required. If you do, the built jar name will be <appname>-<version>.jar.
Note: I'm using gradle 2.5
Details
In order to create a self contained executable jar that you can simply run with:
java -jar appname.jar
you will need:
your jar to include a MANIFEST file pointing to your application main class
all your dependencies (classes from jars outside of your application) to be included or accessible somehow
your MANIFEST file to include the correct classpath
As some other answers point out, you can use some third-party plugin to achieve this, such as shadow or one-jar.
I tried shadow, but didn't like the fact that all my dependencies and their resources were dumped flat out into the built jar together with my application code. I also prefer to minimize the use of external plugins.
Another option would be to use the gradle application plugin as #erdi answered above. Running gradle build will build a jar for you and nicely bundle it with all your dependencies in a zip/tar file. You can also just run gradle installDist to skip zipping.
However, as #jeremyjjbrown wrote in a comment there, the plugin does not create an executable jar per se. It creates a jar and a script which constructs the classpath and executes a command to run the main class of your app. You will not be able to run java -jar appname.jar.
To get the best of both worlds, follow the steps above which create your jar together with all your dependencies as separate jars and add the correct values to your MANIEST.
All of these answers are either wrong or out of date.
The OP is asking for what is known as a "fat jar". That is an exectuable jar which contains all the dependencies so that it requires no outside dependencies in order to run (except for a JRE of course!).
The answer at the time of writing is the Gradle Shadow Jar plugin, explained pretty clearly at Shadow Plugin User Guide & Examples.
I struggled a bit. But this works:
put all these lines somewhere in your build.gradle file (I put them near the top) :
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.4'
}
}
apply plugin: 'com.github.johnrengelman.shadow'
shadowJar {
baseName = 'shadow'
classifier = null
version = null
}
jar {
manifest {
attributes 'Class-Path': '/libs/a.jar'
attributes 'Main-Class': 'core.MyClassContainingMainMethod'
}
}
PS don't worry about any other "repositories", "dependency" or "plugin" lines elsewhere in your build file, and do leave the lines thus inside this "buildscript" block (I haven't a clue why you need to do that).
PPS the Shadow Plugin User Guide & Examples is well-written but doesn't tell you
to include the line
attributes 'Main-Class': 'core.MyClassContainingMainMethod'
where I've put it above. Perhaps because the author assumes you are less clueless than I am, and you probably are. I haven't a clue why we are told to put a strange "Class-Path" attribute like that in, but if it ain't broke don't fix it.
When you then go
> gradle shadowjar
Gradle will hopefully build a fat executable jar under /build/libs (default name "shadow.jar") which you can run by doing this:
> java -jar shadow.jar
I checked quite some links for the solution, finally did the below mentioned steps to get it working. I am using Gradle 2.9.
Make the following changes in your build,gradle file :
1. Mention plugin:
apply plugin: 'eu.appsatori.fatjar'
2. Provide the Buildscript:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "eu.appsatori:gradle-fatjar-plugin:0.3"
}
}
3. Provide the Main Class:
fatJar {
classifier 'fat'
manifest {
attributes 'Main-Class': 'my.project.core.MyMainClass'
}
exclude 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.SF'
}
4. Create the fatjar:
./gradlew clean fatjar
5. Run the fatjar from /build/libs/ :
java -jar MyFatJar.jar

Resources