I'm trying to make examples from grpc-java work.
It's indeed easy if I'm using gradle, however, I'm going to integrate grpc into the project that uses another build system.
I would like to know how to compile and run examples using only protoc, javac and java.
I'm able to generate java sources from .proto sources, but no luck compiling the generated java sources.
I tried 1000 combinations (different classpathes), but nothing works.
> javac RouteGuideGrpc.java
< RouteGuideGrpc.java:3: error: package io.grpc.stub does not exist
import static io.grpc.stub.ClientCalls.asyncUnaryCall;
(99 other compile errors were omitted)
Could anyone show a sequence of commands that will work?
Thank you.
Upd: I'm doing this on Linux.
Upd: I'm using SBT, but it really does not matter. What I really want to understand is how to use javac to compile generated grpc code.
I'm sure I have grpc-core, grpc-netty, grpc-protobuf and grpc-stub in classpath (actually, not sure in anything at this point...).
I actually faced a couple of problems myself trying to migrate from Gradle to SBT.
First you should take advantage of sbt-protobuf plugin which compiles .proto files for you. Make sure to:
Set the path and version of your protoc:
version in PB.protobufConfig := "3.0.0"
protoc in PB.protobufConfig := PATH_PROTOC
If needed set the location of your .proto files (default is src/main/protobuf):
sourceDirectory in PB.protobufConfig := baseDirectory.value / "src" / "main" / "proto"
Finally, set extra options of protoc used by grpc-java. First options sets the path for your protoc-gen-grpc-java plugin bin; and second sets the output path of grpc-java to the same as sbt-protobuf:
protocOptions in PB.protobufConfig ++= Seq(
"--plugin=protoc-gen-grpc-java=" + PATH_GRPC_JAVA_PLUGIN,
"--grpc-java_out=" + baseDirectory.value + "/target/src_managed/main/compiled_protobuf")
I ended up putting a repository with all of this sorted out. Here it is, hope it helps!
The package io.grpc.stub is part of the grpc-stub artifact. To build the code generated component, you need at least protobuf-java, grpc-stub, grpc-protobuf, and grpc-core in your classpath. Depending on how you are compiling, you may also need any protobuf generated classes (the grpc-generated stubs depends on the protobuf-generated protos).
There is documentation for running the code generator manually in the compiler directory, but it doesn't include running javac.
If you continue having problems, double-check that the protoc compiler and protobuf-java have the same version, and protoc-gen-grpc-java and the grpc JARs have the same version.
Ok, I was able to resolve compile-time issues.
I ended up inserting println statements into the build.gradle files that come with grpc to see the actual class-path that is used when compiling those examples.
It turned out that grpc libs had versions 0.9.0, while in my sbt build I was referring to 0.7.2.
Just today libs of version 0.8.0 were put to the maven repository and when I change the version from 0.7.2 to 0.8.0 everything works as expected.
Related
I try to work with JMeter 3.2 source but it's not compiling, It was missing mainly Bouncy Castle jars I added jars but still getting an error:
SMIMEAssertion.java include constructor SMIMESignedParser(BcDigestCalculatorProvider, MimeMultipart) which doesn't exists in JMeter's lib, Code failing:
s = new SMIMESignedParser(new BcDigestCalculatorProvider(), multipart);
s = new SMIMESignedParser(new BcDigestCalculatorProvider(), msg);
I added different jars of Bouncy Castle as latest bcprov-jdk15on-158.jar to older versions bcmail-jdk14-1.46.jar or others as bcpkix-jdk15on-1.55 or bcmail-jdk15-140.jar but still failed to compile
Does anyone knows the correct jars to add?
JMeter uses "ant" to build.
Based on https://github.com/apache/jmeter it looks like they use Travis to build and test (probably on Github).
Based on
before_script:
- test "x$RUN_CHECKSTYLE" != 'x' || ant -Djava.awt.headless=true download_jars install
(https://github.com/apache/jmeter/blob/trunk/.travis.yml)
it appears that you should run
ant download_jars
to get the jars you need. Locate them and add them to your build path.
(And this stuff is exactly why projects are typically migrating to Maven)
Edited in by other user after I wrote it:
Full explanation for building is here:
http://jmeter.apache.org/building.html
A PR of migration to maven is available and should be merged after 3.3 release.
A project runs on Google App Engine. The project has dependency that uses a class that can't be invoked on App Engine due to security constraints (it's not on the whitelist). My (very hacky) solution was to just copy a modified version of that class into my project (matching the original Class's name and package) that doesn't need the restricted class. This works on both dev and live, I assume because my source appears in the classpath before my external dependencies.
To make it a bit cleaner, I decided to put my modified version of that class into it's own project that can be packaged up in a jar and published for anyone else to use should they face this problem.
Here's my build.gradle:
// my jar that has 'fixed' version of Class.
compile files('path/to/my-hack-0.0.1.jar')
// dependency that includes class that won't run on appengine
compile 'org.elasticsearch:elasticsearch:1.4.4'
On my local dev server, this works fine, the code finds my hacked version of the class first at runtime. On live, for some unknown reason, the version in the elasticsearch dependency is loaded first.
I know having two versions of the same class in the classpath isn't ideal but I was hoping I could reliably force my version to be at the start of the classpath. Any ideas? Alternatively, is there a better way to solve this problem?
Not really sure if this is what people visiting this question were looking for, but this was what my problem and a solution that I reached at.
Jar A: contains class XYZ
Jar B: also contains class XYZ
My Project needs Jar B on the classpath before Jar A to be able to get compiled.
Problem is Gradle sorts the dependencies based on alphabetical order post resolving them which meant Jar B will be coming after Jar A in the generated classpath leading to error while compiling.
Solution:
Declare a custom configuration and patch the compileClasspath. This is how the relevant portion of build.gradle might look like.
configurations {
priority
sourceSets.main.compileClasspath = configurations.priority + sourceSets.main.compileClasspath
}
dependencies {
priority 'org.blah:JarB:2.3'
compile 'org.blah:JarA:2.4'
...
}
It's the app engine classloader I should have been investigating, not gradle...
App Engine allows you to customise the class loader JAR ordering with a little bit of xml in your appengine-web.xml. In my case:
<class-loader-config>
<priority-specifier filename="my-hack-0.0.1.jar"/>
</class-loader-config>
This places my-hack-0.0.1.jar as the first JAR file to be searched for classes, barring those in the directory war/WEB-INF/classes/.
...Thanks to a nudge in the right direction from #Danilo Tommasina :)
UPDATE 2020:
I just hit the same problem again and came across my own question... This time, live appengine was loading a different version of org.json than was being loaded in dev. Very frustrating and no amount of fiddling the build script would fix it. For future searchers, if you're getting this:
java.lang.NoSuchMethodError: org.json.JSONObject.keySet()Ljava/util/Set;
It's because it's loading an old org.json dependency from god-knows-where. I fixed it by adding this to my appengine-web.xml:
<class-loader-config>
<priority-specifier filename="json-20180130.jar"/>
</class-loader-config>
You'll also need a matching dependency in build.gradle if you don't already have one:
compile 'org.json:json:20180130'
According to gradle dependencies documentation, the order of dependencies defines the order in the classpath. So, we can simply put the libraries in the correct order in "dependencies".
But beware! here are two rules with higher priorities:
For a dynamic version, a 'higher' static version is preferred over a 'lower' version.
Modules declared by a module descriptor file (Ivy or POM file) are preferred over modules that have an artifact file only.
I'm strugling with using jackson-dataformat-xml on android
I have some very basic code that works fine on oracle jre
JacksonXmlModule module = new JacksonXmlModule();
module.setDefaultUseWrapper(false);
XmlMapper xmlMapper = new XmlMapper(module);
First I tried official documentation adapted for gradle (by me, not sure if done correctly):
compile 'com.fasterxml.jackson.core:jackson-core:2.5.4'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.5.4'
compile 'com.fasterxml.jackson.core:jackson-databind:2.5.4'
compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.5.4'
compile 'org.codehaus.woodstox:woodstox-core-asl:4.4.1'
compile 'javax.xml.stream:stax-api:1.0-2'
Result: gradle fails build time about bundling corelibraries into an application
...
:app:preDexDebug
trouble processing "javax/xml/stream/EventFilter.class":
Ill-advised or mistaken usage of a core class (java.* or javax.*)
when not building a core library.
...
2nd attempt trying to follow Sean's answer
(Basicly he repackages corelibs with prefix names and rebuilds jackson-dataformat-xml to use the prefixed names)
compile 'com.fasterxml.jackson.core:jackson-core:2.1.2'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.1.2'
compile 'com.fasterxml.jackson.core:jackson-databind:2.1.2'
// Repackaged XML-specific libraries
compile 'edu.usf.cutr.android.xml:jackson-dataformat-xml-android:2.1.2'
compile 'edu.usf.cutr.android.xml:stax2-api-android:3.1.1'
compile 'edu.usf.cutr.android.xml:stax-api-android:1.0-2'
compile 'edu.usf.cutr.android.xml:aalto-xml-android:0.9.8'
And build time failed on duplicates
Duplicate files copied in APK META-INF/services/com.fasterxml.jackson.core.ObjectCodec
so added:
packagingOptions {
...
exclude 'META-INF/services/com.fasterxml.jackson.core.JsonFactory'
exclude 'META-INF/services/com.fasterxml.jackson.core.ObjectCodec'
}
When adding the exclusions it builds and deploys, but fails runtime on below stackdump (AFAIK it cant find the SAX provider, even tho it is added to the classpath to my understanding)
edu.usf.cutr.javax.xml.stream.FactoryConfigurationError: Provider com.bea.xml.stream.MXParserFactory not found
at edu.usf.cutr.javax.xml.stream.FactoryFinder.newInstance(FactoryFinder.java:72)
at edu.usf.cutr.javax.xml.stream.FactoryFinder.find(FactoryFinder.java:176)
at edu.usf.cutr.javax.xml.stream.FactoryFinder.find(FactoryFinder.java:92)
at edu.usf.cutr.javax.xml.stream.XMLInputFactory.newInstance(XMLInputFactory.java:136)
at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:97)
at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:85)
at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:82)
at com.fasterxml.jackson.dataformat.xml.XmlMapper.<init>(XmlMapper.java:46)
What is the proper way to move forward on either #1 or #2?
Number 2 is the correct approach (Android doesn't like it when you include classes in the official Java package namespace - but then again, I wrote the original answer so I'm biased ;) ).
I believe the FactoryConfigurationError: Provider com.bea.xml.stream.MXParserFactory not found error is due to a bug in the Android build tools. In previous versions of ADT for Eclipse and Gradle plugin < 0.7.0 the /META-INF/* files are stripped from the JARs during the build process. It seems like >= v0.7.0 shouldn't have the problem according to Google, but from others' reports it sounds like it still may be problematic, and could potentially remove the META-INF/services/javax.xml.stream.XMLInputFactory file, which is required for the platform to register Aalto.
Try the workaround mentioned in AOSP issue 59658 comment 22:
right click on /src/main (where you have /java and /res folders),
select New > Folder > Java Resources Folder,
click Finish (do not change Folder Location),
right click on new /resources folder,
select New > Directory
enter "META-INF" (without quotes),
right click on /resources/META-INF folder,
select New > Directory
enter "services" (without quotes)
copy any file you need into /resources/META-INF/services
For you, in step 10 above you'd need to copy this file into /resources/META-INF/services. In case the file link is broken in the future, the name of the file is javax.xml.stream.XMLInputFactory and it consists of a single line:
com.fasterxml.aalto.stax.InputFactoryImpl
EDIT
If you get a "Error:duplicate files during packaging of APK... Path in archive: META-INF/services/javax.xml.stream.XMLInputFactory", you can try telling Gradle to keep the first occurrence with:
android {
packagingOptions {
pickFirst 'META-INF/services/javax.xml.stream.XMLInputFactory'
}
}
EDIT 2
This bug may be affecting "pickFirst". Please make sure you're running the latest version of Android Studio, and update your local tools and Android Gradle plugin to make sure you're running the most recent version of the tools. This may be fixed in Android Studio 1.3 RC1.
I have attempted to add XmlPull support to jackson xml. Find the forked project here:
https://github.com/finvu/jackson-dataformat-xml
Currently, only supported for version 2.9.6. (clone the branch jackson-dataformat-xml-2.9.6-XmlPull)
Sorry, I am not able to provide detailed documentation due to time constraints. If you have knowledge of git and maven to pull a specific branch and build the jar, then it should be relatively easy.
To those who will be in need of this in the future:
first integrate Jitpack in Your Android app, following their instructions:
https://jitpack.io/
Then paste teh GitHub url of jackson-dataformat-xml on Jitpack sites' corresponding text box. GitHub url is:
https://github.com/FasterXML/jackson-dataformat-xml.
That's it! Enjoy the result. :)
I have a problem with the YUI Compressor for js: I've added version 2.4.7 to my build path in Eclipse ( tried with rhino jar and also without) - no effect whatsoever. I dont get compile errors, I can see the class I've created that implements org.mozilla.javascript.ErrorReporter, but when I try to run the compressor, I get:
java.lang.ClassNotFoundException: org.mozilla.javascript.ErrorReporter from BaseClassLoader#1d81fd2
I know this is an old question but I'm going to add an answer in case anyone else comes across this in a search.
I had the exact same problem. The issue was that yuicompressor-2.4.7.jar wan't in our shared maven repository and so wasn't getting downloaded by the yuicompressor maven plugin. To verify this check your local maven repository for the yuicompressor-2.4.7.jar (usually C:\Users\.m2\repository\com\yahoo\platform\yui\yuicompressor\2.4.7). If it's there then you have a different issue if it's not then this could well be your issue. To fix just upload yuicompressor-2.4.7.jar to your shared repository.
I was trying to use the jira-rest-java-client provided by Atlassian in a Scala program I am developing. I am using Eclipse as my IDE.
When I have an object of type Issue and I try to look at the properties I see there are far fewer properties than are declared in the Java code.
I thought perhaps this was just Eclipse not finding all properties/methods of an object so I tried putting Issue.getSummary() and doing an sbt compile. The compile showed me this error:
Missing dependency 'class javax.annotation.Nullable'
Any ideas?
I found the answer in this issue on googlecode: http://code.google.com/p/guava-libraries/issues/detail?id=1095. To correct the problem in sbt you need to add this dependency:
"com.google.code.findbugs" % "jsr305" % "1.3.+"
The Scala compiler requires all annotation classes in the classpath. As this
class is not available in the classpath, the compilation fails.
In my particular case, the class is not used by the application. Hence, it is sufficient to disable the
fatal-warnings option in the build.
In my built.sbt I had the following line:
scalacOptions ++= Seq("-Yno-adapted-args", "-Ywarn-dead-code", "-Ywarn-numeric-widen", "-Ywarn-value-discard", "-Xfatal-warnings")
I removed the "-Xfatal-warnings" and compilation was successful.