I know there are a lot of questions that seem similar. I have also spent a few hours getting to grips with Gradle multiprojects. But I still don't understand what the best course of action is here. Incidentally I am using Groovy as my coding language, but explanations referencing Java would be just as good.
I have developed an Eclipse Gradle project, "ProjectA", which in particular has a class, IndexManager, which is responsible for creating and opening and querying Lucene indices.
Now I am developing a new Eclipse Gradle project, "ProjectB", which would like to use the IndexManager class from ProjectA.
This doesn't really mean that I would like both projects to be part of a multiproject. I don't want to compile the latest version of ProjectA each time I compile ProjectB - instead I would like ProjectB to be dependent on a specific version of ProjectA's IndexManager. With the option of upgrading to a new version at some future point. I.e. much as with the sorts of dependencies you get from Maven or JCenter...
Both projects have the application plugin, so ProjectA produces an executable .jar file whose name incorporates the version. But currently this contains only the .class files, the resource files, and a file called MANIFEST.MF containing the line "Manifest-Version: 1.0". Obviously it doesn't contain any of the dependencies (e.g. Lucene jar files) needed by the .class files.
The application plugin also lets you produce a runnable distribution: this consists of an executable file (2 in fact, one for *nix/Cygwin, one for Windows), but also all the .jar dependencies needed to run it.
Could someone explain how I might accomplish the task of packaging up this class, IndexManager (or alternatively all the classes in ProjectA possibly), and then including it in my dependencies clause of ProjectB's build.gradle... and then using it in a given file (Groovy or Java) of ProjectB?
Or point to some tutorial about the best course of action?
One possible answer to this which I seem to have found, but find a bit unsatisfactory, appears to be to take the class which is to be used by multiple projects, here IndexManager, and put it in a Gradle project which is specifically designed to be a Groovy library. To this end, you can kick it off by creating the project directory and then:
$ gradle init --type groovy-library
... possible to do from the Cygwin prompt, but not from within Eclipse as far as I know. So you then have to import it into Eclipse. build.gradle in this library project then has to include the dependencies needed by IndexManager, in this case:
compile 'org.apache.lucene:lucene-analyzers-common:6.+'
compile 'org.apache.lucene:lucene-queryparser:6.+'
compile 'org.apache.lucene:lucene-highlighter:6.+'
compile 'commons-io:commons-io:2.6'
compile 'org.apache.poi:poi-ooxml:4.0.0'
compile 'ch.qos.logback:logback-classic:1.2.1'
After this, I ran gradle jar to create the .jar which contains this IndexManager class, initially without any fancy stuff in the manifest (e.g. name, version). And I put this .jar file in a dedicated local directory.
Then I created another Gradle project to use this .jar file, the critical dependency here being
compile files('D:/My Documents/software projects/misc/localJars/XGradleLibExp.jar' )
The file to use this class looks like this:
package core
import XGradleLibExp.IndexManager
class Test {
public static void main( args ) {
println "hello xxx"
Printer printer = new Printer()
IndexManager im = new IndexManager( printer )
def result = im.makeIndexFromDbaseTable()
println "call result $result"
}
}
class Printer {
def outPS = new PrintStream(System.out, true, 'UTF-8' )
}
... I had designed IndexManager to use an auxiliary class, which had a property outPS. Groovy duck-typing means you just have to supply anything with such a property and hopefully things work.
The above arrangement didn't run: although you can do build and installdist without errors, the attempt to execute the distributed executable fails because the above 6 compile dependency lines are not present in build.gradle of the "consumer" project. When you put them in this "consumer" Gradle project's build.gradle, it works.
No doubt you can add the version to the generated .jar file, and thus keep older versions for use with "consumer" projects. What I don't understand is how you might harness the mechanism which makes the downloading and use of the dependencies needed by the .jar as automatic as we are used to for things obtained from "real repositories".
PS in the course of my struggles today I seem to have found that Gradle's "maven-publish" plugin is not compatible with Gradle 5.+ (which I'm using). This may or may not be relevant: some people have talked of using a "local Maven repository". I have no idea whether this is the answer to my problem... Await input from an über-Gradle-geek... :)
You should be able to update the Eclipse model to reflect this project-to-project dependency. It looks something like this (in ProjectB's build.gradle):
apply plugin: 'eclipse'
eclipse {
classpath.file.whenMerged {
entries << new org.gradle.plugins.ide.eclipse.model.ProjectDependency('/ProjectA')
}
project.file.whenMerged {
// add a project reference, which should show up in /ProjectB/.project's <projects> element
}
}
These changes may be to the running data model, so they may not actually alter the .classpath and .project files. More info can be found here: https://docs.gradle.org/current/dsl/org.gradle.plugins.ide.eclipse.model.EclipseModel.html
This issue is discussed here: http://gradle.1045684.n5.nabble.com/Gradle-s-Eclipse-DSL-and-resolving-dependencies-to-workspace-projects-td4856525.html and a bug was opened but never resolved here: https://issues.gradle.org/browse/GRADLE-1014
Trying to find out if it's possible to use javac plugins in Bazel build system.
Input:
there is a javac plugin jar in the Maven Central
I want to configure Bazel in a way to have it on the javac classpath during compilation
I.e. I have the following in my WORKSPACE file:
maven_jar (
name = "traute",
artifact = "tech.harmonysoft:traute-javac:1.1.1"
)
and want to do something like below:
java_library (
...
javacopts = ["-classpath #traute://jar", "-Xplugin:Traute"]
)
Unfortunately, that doesn't work - a jar reference is not substituted to an actual path.
Bazel documentation doesn't provide an answer as well, it just mentions that only annotation processors are supported out of the box.
Is it the case that anybody more experienced with Bazel can hint me on the way to apply a javac plugin?
AFK so low on links but take a look at using $(location expansion //target) and also add the target to the deps attribute (data attribute might be sufficient)
Using current JDK build 9-ea+143's javax.tools.JavaCompiler tool, I can compile the simple (empty) example module without an error:
module com.foo.bar { }
If I add open as in:
open module com.foo.bar { }
...the compiler error reads:
/module-info.java:1: error: class, interface, or enum expected
open module com.foo.bar {
^
Syntax based on http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html
Is the current JDK 9 build not up-to-date with this spec or am I missing an option to be passed to JavaCompiler?
To get the newest Jigsaw features, you need to use the Jigsaw EA build (as opposed to the regular EA builds). I created a GitHub repo exploring open packages and modules (to make reflection work) and also wrote about it - it definitely works on b146.
I'm trying to build OpenCV on my Windows 7 machine. To include the contrib modules I have added the OPENCV_EXTRA_MODULES_PATH in CMake-gui. The opencv-300.jar and opencv-300.dll have been created but I can not find the Java classes to use the extra modules. Am I missing an option in the make configuration? Is it possible to use these extra modules from Java?
i've the same problem and i resolved in this way. I imagine that you had downloaded from contrib repo the specific version match with the opencv version if you want to build. So go in directory and enter, for example, face module directory; in this directory there is a file called CMakeLists.txt that you have to edit. This file should be like this:
set(the_description "Face recognition etc")
ocv_define_module(face opencv_core opencv_imgproc opencv_objdetect WRAP python)
# NOTE: objdetect module is needed for one of the samples
If you want to have the org.opencv.face package in your opencv-3xx.jar library you have to modify the 2nd line of the file in this way:
ocv_define_module(face opencv_core opencv_imgproc opencv_objdetect WRAP python java)
Then you have to compile opencv as depicted in the Readme.md of the contrib repo https://github.com/itseez/opencv_contrib
Obviously the same thing is valid for all the contrib modules if you want to add to your opencv-3xx.jar library.
I hope that this solution works for you, bye!
I'm new to protobufs and was trying to learn more about using them. I've downloaded the protobuf packaged from here. There is a README.txt file inside the examples folder of the archive which gives instructions on how to build 2 example applications. However when I follow those instructions for building the java application:
make java
I get a lot of errors followed by:
100 errors
make: * [javac_middleman] Error 1
All of the 100 errors seem to be classpath related, as this is a typical example:
com/example/tutorial/AddressBookProtos.java:37: error: package com.google.protobuf does not exist
Any ideas about how to get passed this?
The problem is that for some reason protobuf jar is not added to the classpath during compilation. To fix it you should open examples/Makefile and add -cp protobuf-java-2.4.1.jar at the end of java complilation line javac AddPerson.java ListPeople.java com/example/tutorial/AddressBookProtos.java.
P.S. If you built you protobufs with maven the jar is located at ~/.m2/repository/com/google/protobuf/protobuf-java/2.4.1/protobuf-java-2.4.1.jar (version of the jar might be different)