-
Notifications
You must be signed in to change notification settings - Fork 283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
macros that reference Java libraries don't work #445
Comments
Yep. That’s an issue. I think bazel May be able to handle this by possibly hitching to its handling of annotation processors, but maybe there are some speed bumps there. In the worst case we can write some rule that re-exports the runtime path as a compile time for use in macros. |
As described in the linked bazel issue above this can be improved even more with a scalainfo provider. We can’t totally migrate to new style providers yet because intellij does not support JavaInfo fully yet as far as I know. I’d rather wait to solve this until we can do it in a migration to only new style providers. |
Note: the fix of repairing the classpath issue can be done now, at the cost of java dependencies seeing the full classpath. We could do that and then narrow the classpath when we move to only using providers. |
Yeah, this is a tad unfortunate. I ran into a variant of this issue when
trying to get scalac plugins to work on a really old variant of the rules.
My main regret is that the macro implementations should generally only be
using a small subset of the total dependencies (as they are really only
fiddling with ASTs) and so exposing all dependencies is a bit pessimistic.
I suppose people could mitigate the impact of this by only having their
scala_macro_library rules contain the macro implementations. (I can test
this myself later but I don't think the macro invocations like def blah =
macro MacroImpl need to be a scala_macro_library?)
…On Sat, Apr 21, 2018, 4:48 PM P. Oscar Boykin ***@***.***> wrote:
Note: the fix of repairing the classpath issue can be done now, at the
cost of java dependencies seeing the full classpath. We could do that and
then narrow the classpath when we move to only using providers.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#445 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AA9_-FNjAoiMWfha0Kt_S20DADROK9HGks5tq8VMgaJpZM4Sw10C>
.
|
Is the idea here to have If a some library depends on, say, apache commons directly and via a |
Also having this issue when trying to use with Artifact in Maven2: The workaround suggested by the original poster does work for me, just the Hoping to see an update! |
Yes, we can do something better. I think the right solution is to rexport the full transitive runtime classpath as the compile classpath for https://github.com/johnynek/bazel-deps does this, for instance. One problem with bazel is that there are many ways you could consume external maven dependencies. It is hard to give someone feedback when they just describe something not working without knowing how they are depending on the code. We should add a local test showing two issues:
|
It seems I'm having exacly this issue when depending on I've tried using |
@ioleo can you post the stack trace you get and the |
@johnynek So, I've reverted to my original code already:
which
As you can see I'm importing from
As for the
The only diffrence beuing replacing in However this leads to the same build error. About the filegroup suggested solution as far as I understand it's when I incorporate the jar in my own repo (which I don't want here --> I want to reference maven artifact). Please forgive any misconceptions, I'm just getting started with bazel. |
The class that is missing is: org/apache/avro/Schema What jar is that in? It probably isn’t in a scala jar and that’s the issue. Macros can call non macro code even java code. In such cases now we have an issue because we need to remove the ijar and add the runtime jar. A work around if you are using my bazel-deps tool is to say Avro is a scala/unmangled for the language. This will use scala import for avro which makes it not use ijar. You really don’t need ijar for external dependencies since they don’t change often and when they do even the ijar likely changes. We should probably update bazel deps to not use ijar even for java dependencies. That would reduce these issues but still not totally solve them since we still can have this kind of problem for macro code defined inside the repo. |
@johnynek It's used by the avro4s-macro library. The dependency is added via sbt plugin. I agree I don't need the IJAR for the external depepency. As far as I understand, using
How do I do that? |
If you add the avro jar to your dependencies and give it a |
I've tried both:
and
and got this error on running
The problem is obviously missing scala version.
|
You need to put avro itself. Maybe .org.apache:avro? I don’t really know. You need to put the artifact with the missing class into scala_import. |
Hmm.. actually I already have the
And that version does contain the |
@johnynek Alright, actually changing the above to:
fixed the problem! Thanks for help <3! Now I can build without the |
What's going on is that this is forcing this jar to be seen as a scala_import instead of java_import. It's not clear where to document it. This is a hack work around. I think it would be better to fix the scala_macro_library rule so we don't need the hack and let this issue be the documentation for the rare cases of people that hit the issue (which isn't very common, most users don't write macros, and those that do tend to depend on scala libraries). |
We are using rules_jvm_external https://github.com/bazelbuild/rules_jvm_external and we faced the same problem, May be I can try to implement a fix for the Thanks! |
here is the code for scala_library:
note the parameter This line here:
if we are a macro should use Now, there is a complication that is significant here: if you depend on A and B and both depend on C. And A is not a macro but B is, you will get both the ijar for C and the full jar for C on the classpath if we are not careful. scalac/javac won't error in the case that there are duplicate classnames on the classpath, but it will take the first one it finds, so you can't count on getting the right jar. Since not everything needs the compile jar, this will manifest as sometimes working and sometimes not. The correct solution would be some pass that removes ijars that need to be removed. A way to do that would be to propagate all the ijars to delete in the scala provider. So, before you compile, you iterate all the compile jars, but remove any that are in the deleted set (which have been replaced by full jars). I think that will cover it. I'm happy to help you work through this problem. I think a good first step is writing test cases that show the bug, then implement the simple strategy that can duplicate the jars, then write a test that fails that shows the above bug about duplicate classes, then finally fix that with the solution that won't include duplicate jars. |
Just wanted to add that we have a pending PR which refractors this repo
significantly and that until I merge it in (couple of weeks) we probably
won’t be merging other PRs to ease its merge.
If you’re interested it’s probably still a good idea to iterate on this
since redoing it over the merged PR shouldn’t be that hard.
Finally I’m a bit concerned from the performance impact of the solution
Oscar outlined but I’m not sure there is an alternative.
We’ll need to discuss this over concrete code.
…On Mon, 18 Nov 2019 at 21:46 P. Oscar Boykin ***@***.***> wrote:
here is the code for scala_library:
https://github.com/bazelbuild/rules_scala/blob/26cf9b74fc46f1e9a970c97837447549ed7257b6/scala/private/rules/scala_library.bzl#L43
note the parameter non_macro_lib. This if False if we are dealing with a
macro, and True for a regular library.
This line here:
https://github.com/bazelbuild/rules_scala/blob/26cf9b74fc46f1e9a970c97837447549ed7257b6/scala/private/rules/scala_library.bzl#L112
if we are a macro should use transitive_runtime_jars (I think that's the
field name) for all downstream nodes that depend on this library. This is
because compiletime for a macro can use the runtime classpath.
Now, there is a complication that is significant here: if you depend on A
and B and both depend on C. And A is not a macro but B is, you will get
both the ijar for C and the full jar for C on the classpath if we are not
careful. scalac/javac won't error in the case that there are duplicate
classnames on the classpath, but it will take the first one it finds, so
you can't count on getting the right jar. Since not everything needs the
compile jar, this will manifest as sometimes working and sometimes not.
The correct solution would be some pass that removes ijars that need to be
removed. A way to do that would be to propagate all the ijars to delete in
the scala provider. So, before you compile, you iterate all the compile
jars, but remove any that are in the deleted set (which have been replaced
by full jars).
I think that will cover it. I'm happy to help you work through this
problem. I think a good first step is writing test cases that show the bug,
then implement the simple strategy that can duplicate the jars, then write
a test that fails that shows the above bug about duplicate classes, then
finally fix that with the solution that won't include duplicate jars.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#445?email_source=notifications&email_token=AAKQQFY4XO2QLJWIOP5YI7DQULWJLA5CNFSM4EWDLUBKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEELVWKI#issuecomment-555178793>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAKQQF546Y3AC6MMX2SLCWTQULWJLANCNFSM4EWDLUBA>
.
|
related somewhat to #366 |
Hey, folks. We've published a proposal to port some of the features from lucidsoftware/rules_scala, an alternative Scala ruleset that we maintain. Getting macro dependencies to work properly is one of them. Here's a link to the relevant proposal section that details specifically what we'd like to do, and a link to an issue we're using to track the broader effort: The tracking issue for this effort Are folks on board with our approach to solving this issue? We were hoping to take on this task in the near future. |
The following example shows that a macro that calls a Java library doesn't work. This is related to bazelbuild/bazel#632. The library jar for
:JavaLib
on compile-time classpath only contains the compile-time API of that library, but the macro needs the complete implementation to be available at compile-time.Demo: https://gist.github.com/cushon/a97470ed69f61d966c94bcde1ed018f0
Setup:
Building
:HelloLib
fails:Disabling ijar and header compilation works around the bug:
The text was updated successfully, but these errors were encountered: