GithubHelp home page GithubHelp logo

Comments (14)

raphw avatar raphw commented on August 22, 2024

The documentation states: A Byte Buddy plugin that transforms a project's production class files where all scopes but the test scope are included. This means that the dependant classes will be resolved, and can be analysed during the build, for example as annotation properties. Any Maven module can however only transform the (test) classes that it defines. Dependencies cannot be instrumented during a build.

from byte-buddy.

LarsBodewig avatar LarsBodewig commented on August 22, 2024

I found a related issue where you advise to use Plugin.Engine.Default to transform a library's jar file. How do I do that?

Does my custom plugin need to implement Plugin.Engine or do I to extend the ByteBuddy mojo to load the library jar and pass the classes as Source?

from byte-buddy.

raphw avatar raphw commented on August 22, 2024

You can apply an engine to any folder or jar file, just as you can specify any folder or jar file as a destination. If you downloaded the jar during a build and transformed it, you might be able to substitute the dependency later. This is however related to how you run your app.

from byte-buddy.

LarsBodewig avatar LarsBodewig commented on August 22, 2024

But to apply the engine to the jar file I need to use a custom mojo or can I configure the ByteBuddyMojo to do that? Downloading the jar during the build is no problem.

from byte-buddy.

raphw avatar raphw commented on August 22, 2024

There is now, good point, this was missing.

Could you build Byte Buddy from master and see if that works for your real-life scenario? You would need to use the transform-location target and specify source and target. If you want to add other locations for class file resolution, you would need to specify locations as dependencies which will be resolved and added.

from byte-buddy.

LarsBodewig avatar LarsBodewig commented on August 22, 2024

The goal fails with a PluginConfigurationException:
Unable to parse configuration of mojo net.bytebuddy:byte-buddy-maven-plugin:1.14.19-SNAPSHOT:transform-location for parameter dependency: Cannot create instance of class net.bytebuddy.build.maven.MavenCoordinate

due to public List<MavenCoordinate> dependencies;.

I changed it to List<CoordinateConfiguration> and resolved it to an artifact in resolveClassPathElements().

                Map<Coordinate, String> coordinates = new HashMap<Coordinate, String>();
                if (project.getDependencyManagement() != null) {
                    for (Dependency dependency : project.getDependencyManagement().getDependencies()) {
                        coordinates.put(new Coordinate(dependency.getGroupId(), dependency.getArtifactId()), dependency.getVersion());
                    }
                }
                String managed = coordinates.get(new Coordinate(project.getGroupId(), project.getArtifactId()));
                for (CoordinateConfiguration dependency : dependencies) {
                    MavenCoordinate mavenCoordinate = dependency.asCoordinate(project.getGroupId(), project.getArtifactId(), managed == null ? project.getVersion() : managed, project.getPackaging());

I also had to change the apply method to pass the classpathElements as a compound source since the library jar was never transformed when I configured my source as ${project.build.sourceDirectory}

            List<Plugin.Engine.Source> resolved = new ArrayList<Plugin.Engine.Source>();
            List<String> combined = new ArrayList<String>(elements);
            combined.add(this.target);
            for (String element : combined) {
                File e = new File(element);
                if (e.isDirectory()) {
                    resolved.add(new Plugin.Engine.Source.ForFolder(e));
                } else if (e.exists()) {
                    resolved.add(new Plugin.Engine.Source.ForJarFile(e));
                } else {
                    throw new MojoFailureException("Source location does not exist: " + e);
                }
            }
            Plugin.Engine.Source compound = new Plugin.Engine.Source.Compound(resolved);

however I still have issues with missing classes from my compile classpath (located in a 3rd jar, not the one I pass in the configuration/that I try to transform). Since the transform goal works fine, I tried adding project.getCompileClasspathElements to the compound source as well but without any luck. Do you have any advise?

I also noticed, that you changed a line in ByteBuddyMojo.transform to .apply(source, target, factories); so I tried changing it back to .apply(source, new Plugin.Engine.Target.ForFolder(file), factories); (since you passed root before the change which became file) but could not see any difference.

Also the mvnw fails due to checksums, but since the README advises to use mvn to build, I guess that's fine.

from byte-buddy.

raphw avatar raphw commented on August 22, 2024

Thanks for the first hint, I have fixed that on master.

As for the exception: You have to specify any dependencies as: <dependencies><dependency>...</dependency></dependencies> in the configuration block of the plugin. As you point to a location or jar file, the plugin does not know about any possible Maven coordinates that need to be included, so you would need to specify those manually. I just gave this a test myself and this seems to work.

from byte-buddy.

LarsBodewig avatar LarsBodewig commented on August 22, 2024

Maybe I misunderstood. I figured the list of dependencies for the goal was a way to specify the libraries that should be additionally transformed, while I hoped other project dependencies would still be available on the classpath. I think I can work around it though, I will test it tomorrow.

from byte-buddy.

raphw avatar raphw commented on August 22, 2024

I can add a flag to include the class path. You are right that it will make sense in many scenarios. As it is right now, you can transform any jar or folder, even outside the project, so it is a bit more generic. Also, a library will likely have less classes available than the project itself, so the scope can be reduced. But I will add a convenience option.

from byte-buddy.

raphw avatar raphw commented on August 22, 2024

Can you try with the latest version? transform-location will now include the class path. transform-location-empty is now the previous behavior.

from byte-buddy.

LarsBodewig avatar LarsBodewig commented on August 22, 2024

I tried transform-location and transform-location-extended but I probably still do something wrong.

                  <configuration>
                    <transformations>
                        <transformation>
                            <groupId>mygroup</groupId>
                            <artifactId>myplugin</artifactId>
                            <version>1.0.0</version>
                            <plugin>my.Plugin</plugin>
                        </transformation>
                    </transformations>
                    <source>${project.build.outputDirectory}</source>
                    <target>${project.build.outputDirectory}</target>
                    <dependencies>
                        <dependency>
                            <groupId>3rd.party</groupId>
                            <artifactId>library</artifactId>
                            <version>1.0.0</version>
                        </dependency>
                    </dependencies>
                </configuration>

If I set source to ${project.build.outputDirectory} my own classes are being transformed, but not the 3rd party library.

If I use the maven-dependency-plugin to download the 3rd party jar inbefore and set source to ${project.build.directory}/dependency it transforms neither the java classes nor the library (since that folder does not contain class files but jar files which are not detected).

I have to specifiy the full jar name to transform the 3rd party library, which will only ever work for one jar file (and likely skips the purpose of configuring the dependency separately).

<source>${project.build.directory}/dependency/library-1.0.0.jar</source>

Maybe it's not necessary to add 5 new mojos but instead just extend the existing mojos with List<CoordinateConfiguration> dependencies to specify additional libraries to be processed (additionally to the local classes, that the other mojos already process and without configuring a source)?

from byte-buddy.

raphw avatar raphw commented on August 22, 2024

I am not sure what you are trying to accomplish, but I would copy your compiled classes and the dependencies to a custom location using: https://maven.apache.org/components/plugins/maven-dependency-plugin/examples/unpacking-project-dependencies.html

Then you can apply the Byte Buddy plugin on this exploded folder and pack the modified app in one app.

The reason I need to add that many Mojos is that Maven requires annotations to resolve a given dependency scope.

from byte-buddy.

raphw avatar raphw commented on August 22, 2024

I added another target for this exact use case. Given the Maven API, I think this is the best approach. If you have a folder with all dependencies, using transform-dependencies should now do what you expect if that folder contains all relevant jar files.

Could you try this out?

from byte-buddy.

LarsBodewig avatar LarsBodewig commented on August 22, 2024

I was able to achieve what I wanted by using two goals at once now:

  • transform for my local project classes where my transformation also needs project dependency from the classpath and
  • transform-location/transform-location-empty to transform another 3rd party library after copying and unpacking it with the maven-assembly-plugin (since maven-dependency-plugin does not support transitive dependencies on copy/unpack).

I also tested out transform-dependencies to transform a folder of jar files, however with the maven-assembly-plugin it's easier to just unpack the dependencies immediately. This way I also skipped the need to specify the dependency in the plugin configuration so I can't say if that works as expected.

Overall, achieves what I'd like to use the plugin for :) I can also run my tests with gradle, if you plan on bringing this feature to the byte-buddy-gradle-plugin.

from byte-buddy.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.