├── .gitignore ├── Jenkinsfile ├── LICENSE ├── README.md ├── invesdwin-instrument-parent ├── .gitignore ├── invesdwin-instrument-burningwave │ ├── .gitignore │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ ├── burningwave.static.properties │ │ └── de │ │ └── invesdwin │ │ └── instrument │ │ └── burningwave │ │ └── BurningwaveInstrumentationAgent.java ├── invesdwin-instrument │ ├── .gitignore │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ ├── META-INF │ │ │ └── ctx.spring.weaving.xml │ │ │ └── de │ │ │ └── invesdwin │ │ │ └── instrument │ │ │ ├── DynamicInstrumentationLoader.java │ │ │ ├── DynamicInstrumentationProperties.java │ │ │ ├── DynamicInstrumentationReflections.java │ │ │ └── internal │ │ │ ├── AgentClassLoaderReference.java │ │ │ ├── AgentInstrumentationInitializer.java │ │ │ ├── DummyAttachProvider.java │ │ │ ├── DynamicInstrumentationAgent.java │ │ │ ├── DynamicInstrumentationAgent.java.template │ │ │ ├── DynamicInstrumentationAgentCompiler.java │ │ │ ├── DynamicInstrumentationAgent_1.java │ │ │ ├── DynamicInstrumentationAgent_10.java │ │ │ ├── DynamicInstrumentationAgent_11.java │ │ │ ├── DynamicInstrumentationAgent_12.java │ │ │ ├── DynamicInstrumentationAgent_13.java │ │ │ ├── DynamicInstrumentationAgent_14.java │ │ │ ├── DynamicInstrumentationAgent_15.java │ │ │ ├── DynamicInstrumentationAgent_16.java │ │ │ ├── DynamicInstrumentationAgent_17.java │ │ │ ├── DynamicInstrumentationAgent_18.java │ │ │ ├── DynamicInstrumentationAgent_19.java │ │ │ ├── DynamicInstrumentationAgent_2.java │ │ │ ├── DynamicInstrumentationAgent_20.java │ │ │ ├── DynamicInstrumentationAgent_21.java │ │ │ ├── DynamicInstrumentationAgent_22.java │ │ │ ├── DynamicInstrumentationAgent_23.java │ │ │ ├── DynamicInstrumentationAgent_24.java │ │ │ ├── DynamicInstrumentationAgent_25.java │ │ │ ├── DynamicInstrumentationAgent_3.java │ │ │ ├── DynamicInstrumentationAgent_4.java │ │ │ ├── DynamicInstrumentationAgent_5.java │ │ │ ├── DynamicInstrumentationAgent_6.java │ │ │ ├── DynamicInstrumentationAgent_7.java │ │ │ ├── DynamicInstrumentationAgent_8.java │ │ │ ├── DynamicInstrumentationAgent_9.java │ │ │ ├── DynamicInstrumentationLoadAgentMain.java │ │ │ ├── JdkFilesFinder.java │ │ │ ├── RemoveFinalModifierJava9.java │ │ │ └── compile │ │ │ ├── DynamicInstrumentationClassInfo.java │ │ │ └── DynamicInstrumentationCompiler.java │ │ └── test │ │ └── java │ │ ├── burningwave.static.properties │ │ └── de │ │ └── invesdwin │ │ └── instrument │ │ ├── DynamicInstrumentationLoaderTest.java │ │ └── internal │ │ └── compile │ │ └── DynamicInstrumentationAgentGenerator.java └── pom.xml └── tests ├── springboot-devtools-testapp ├── .gitignore ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── libs │ └── invesdwin-instrument-1.0.14.jar ├── settings.gradle └── src │ ├── main │ ├── java │ │ ├── com │ │ │ └── sample │ │ │ │ └── api │ │ │ │ └── server │ │ │ │ ├── Application.java │ │ │ │ ├── config │ │ │ │ ├── ApplicationConfiguration.java │ │ │ │ ├── AsyncConfiguration.java │ │ │ │ ├── CacheConfiguration.java │ │ │ │ └── LoadTimeWeavingConfiguration.java │ │ │ │ ├── core │ │ │ │ ├── dto │ │ │ │ │ └── UserDTO.java │ │ │ │ └── service │ │ │ │ │ ├── UserService.java │ │ │ │ │ └── impl │ │ │ │ │ └── UserServiceImpl.java │ │ │ │ ├── test │ │ │ │ ├── TestAspect.java │ │ │ │ ├── TestAspectAnnotation.java │ │ │ │ └── TestAspectUseCase.java │ │ │ │ └── web │ │ │ │ └── controller │ │ │ │ └── UserController.java │ │ └── lombok │ │ │ └── launch │ │ │ └── AgentAccessor.java │ └── resources │ │ ├── META-INF │ │ └── aop.xml │ │ ├── application.properties │ │ ├── burningwave.static.properties │ │ ├── ehcache.xml │ │ ├── logback.xml │ │ └── lombok.config │ └── test │ └── java │ └── com │ └── sample │ └── api │ └── server │ └── core │ └── service │ ├── AbstractTestCase.java │ └── UserServiceTest.java └── springboot-instrumentation-testapp ├── .gitignore ├── pom.xml └── src └── main └── java └── de └── invesdwin └── springboot └── instrumentation └── testapp └── Main.java /.gitignore: -------------------------------------------------------------------------------- 1 | /.project 2 | **/.DS_Store 3 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | @Library('global-shared-library') _ 2 | 3 | buildTestDeploy(pomFolderPath: "invesdwin-instrument-parent") 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | 167 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # invesdwin-instrument 2 | 3 | This is an instrumentation java agent that is able to load itself into the running JVM. It is able to dynamically setup springs `InstrumentationLoadTimeWeaver` to enable support for aspects without having to start the JVM with an explicit java agent. 4 | 5 | ## Maven 6 | 7 | Releases and snapshots are deployed to this maven repository: 8 | ``` 9 | https://invesdwin.de/repo/invesdwin-oss-remote/ 10 | ``` 11 | 12 | Dependency declaration: 13 | ```xml 14 | 15 | de.invesdwin 16 | invesdwin-instrument 17 | 1.0.14 18 | 19 | ``` 20 | 21 | There is no plan to publish artifacts to maven central, see answer [here](https://github.com/invesdwin/invesdwin-instrument/issues/17#issuecomment-728772422) for alternatives. 22 | 23 | ## Usage 24 | 25 | Simply define a static initializer like this: 26 | ```java 27 | static { 28 | DynamicInstrumentationLoader.waitForInitialized(); //dynamically attach java agent to jvm if not already present 29 | DynamicInstrumentationLoader.initLoadTimeWeavingContext(); //weave all classes before they are loaded as beans 30 | } 31 | ``` 32 | 33 | 34 | ### Spring-Boot 35 | 36 | With [spring-boot](http://projects.spring.io/spring-boot/) you have to ensure that the context in the aspects is updated by importing the one responsible for initializing the load time weaving into the spring-boot configuration: 37 | ```java 38 | @SpringBootApplication 39 | /** 40 | * Make @Configurable work via @EnableLoadTimeWeaving. 41 | * If it does not work, alternatively you can try: 42 | * @ImportResource(locations = "classpath:/META-INF/ctx.spring.weaving.xml") 43 | */ 44 | @EnableLoadTimeWeaving 45 | public class MySpringBootApplication { 46 | public static void main(final String[] args) { 47 | DynamicInstrumentationLoader.waitForInitialized(); //dynamically attach java agent to jvm if not already present 48 | DynamicInstrumentationLoader.initLoadTimeWeavingContext(); //weave all classes before they are loaded as beans 49 | //org.aspectj.weaver.loadtime.Agent.agentmain("", InstrumentationSavingAgent.getInstrumentation()); //workaround for spring-boot-devtools RestartLauncher 50 | SpringApplication.run(MySpringBootApplication.class, args); //start application, load some classes 51 | } 52 | } 53 | ``` 54 | To enable the spring aspects, just add the [spring-aspects.jar](http://mvnrepository.com/artifact/org.springframework/spring-aspects) dependency to your project, they are enabled directly, others might need a [aop.xml](http://www.springbyexample.org/examples/aspectj-ltw-aspectj-config.html) to be enabled. Note that the "ctx.spring.weaving.xml" is part of the invesdwin-instrument jar. 55 | 56 | Make sure that the instrumentation is loaded before the classes of the aspects or the classes that use the aspects are loaded by the classloader. Only classes that get loaded after initializing load time weaving will be successfully woven by aspectj. 57 | 58 | Please note that you need to have a JDK installed with `tools.jar` available in it for this to work properly (this is not required anymore since Java 9). 59 | Alternatively just load the invesdwin-instrument jar via the `-javaagent:/path/to/invesdwin-instrument.jar` JVM parameter if you only have a JRE installed. The dynamic loading will be skipped then. 60 | 61 | For a sample usage see the junit test cases in the [invesdwin-aspects](https://github.com/subes/invesdwin-aspects) project or the spring-boot example project in [invesdwin-nowicket](https://github.com/subes/invesdwin-nowicket). 62 | 63 | ### Spring-Boot-Devtools 64 | 65 | Note that [spring-boot-devtools](https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.devtools) uses a `org.springframework.boot.devtools.restart.RestartLauncher` that reinitializes the application in a nested classloader. This restart mechanism can be disabled via the system property `spring.devtools.restart.enabled=false`, but that might disable functionality of spring-boot-devtools. To work around this, use `org.aspectj.weaver.loadtime.Agent.agentmain("", InstrumentationSavingAgent.getInstrumentation());` inside the nested classloader to reinitialize AspectJ. Also you might have to add the AspectJ weaver option `-Xreweavable` to make it work properly. For more details see: https://github.com/invesdwin/invesdwin-instrument/issues/24 66 | 67 | ### Testing Aspects inside Unit Tests 68 | 69 | See discussion [here](https://stackoverflow.com/a/70348250/67492). The workaround is to use the aspects inside nested classes that are loaded after invesdwin-instrument is initialized by the unit test class. Example [here](https://github.com/invesdwin/invesdwin-context-persistence/blob/master/invesdwin-context-persistence-parent/invesdwin-context-persistence-jpa-hibernate/src/test/java/de/invesdwin/context/persistence/jpa/hibernate/MultiplePersistenceUnitsTest.java). 70 | 71 | ### Burningwave Java Agent 72 | 73 | With invesdwin-instrument-burningwave you can sometimes launch external applications on newer Java versions without having to add any `--add-opens` arguments (or at least test if this is the only problem with newer Java versions). The java agent automatically opens all modules when being used via `StaticComponentContainer.Modules.exportAllToAll()` from [burningwave](https://www.burningwave.org/). This agent needs to be specified manually via `-javaagent:/path/to/invesdwin-instrument-burningwave.jar`. It does not load itself into the running process because you can just call burningwave yourself if you can modify your application anyway. 74 | 75 | ## Support 76 | 77 | If you need further assistance or have some ideas for improvements and don't want to create an issue here on github, feel free to start a discussion in our [invesdwin-platform](https://groups.google.com/forum/#!forum/invesdwin-platform) mailing list. 78 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/.gitignore: -------------------------------------------------------------------------------- 1 | /.checkstyle 2 | /.classpath 3 | /log 4 | /target 5 | /activemq-data 6 | /.fbprefs 7 | /cache 8 | /.settings 9 | /.project 10 | /*.hprof 11 | /.jrctemp 12 | /.invesdwin 13 | /nbproject 14 | /bin 15 | /.springBeans 16 | /.factorypath 17 | /.attach_pid* 18 | /**/.DS_Store 19 | /.idea 20 | /**/*.iml 21 | /.sessions 22 | /**/.~lock.* 23 | /.pydevproject 24 | /Report_*.java 25 | /octave-workspace 26 | /hs_err_pid*.log 27 | /*.Rout 28 | /.apt* 29 | /ajcore.*.txt 30 | /.temp-*.txt 31 | /dependency-reduced-pom.xml 32 | /META-INF 33 | /.Rproj.user 34 | /.Rhistory 35 | /.RData 36 | /.Ruserdata 37 | /.vite 38 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument-burningwave/.gitignore: -------------------------------------------------------------------------------- 1 | /.checkstyle 2 | /.classpath 3 | /log 4 | /target 5 | /activemq-data 6 | /.fbprefs 7 | /cache 8 | /.settings 9 | /.project 10 | /*.hprof 11 | /.jrctemp 12 | /.invesdwin 13 | /nbproject 14 | /bin 15 | /.springBeans 16 | /.factorypath 17 | /.attach_pid* 18 | /**/.DS_Store 19 | /.idea 20 | /**/*.iml 21 | /.sessions 22 | /**/.~lock.* 23 | /.pydevproject 24 | /Report_*.java 25 | /octave-workspace 26 | /hs_err_pid*.log 27 | /*.Rout 28 | /.apt* 29 | /ajcore.*.txt 30 | /.temp-*.txt 31 | /dependency-reduced-pom.xml 32 | /META-INF 33 | /.Rproj.user 34 | /.Rhistory 35 | /.RData 36 | /.Ruserdata 37 | /.vite 38 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument-burningwave/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | de.invesdwin 7 | invesdwin-instrument-parent 8 | 1.0.15-SNAPSHOT 9 | 10 | invesdwin-instrument-burningwave 11 | jar 12 | 13 | 14 | 15 | org.burningwave 16 | core 17 | 18 | 19 | 20 | 21 | 22 | 23 | org.apache.maven.plugins 24 | maven-jar-plugin 25 | 26 | 27 | 28 | 29 | de.invesdwin.instrument.burningwave.BurningwaveInstrumentationAgent 30 | 31 | de.invesdwin.instrument.burningwave.BurningwaveInstrumentationAgent 32 | false 33 | false 34 | 35 | 36 | 37 | 38 | 39 | 41 | org.apache.maven.plugins 42 | maven-shade-plugin 43 | 44 | 45 | package 46 | 47 | shade 48 | 49 | 50 | 51 | 52 | 53 | de.invesdwin 54 | invesdwin-maven-plugin 55 | ${project.version.invesdwin-maven-plugin} 56 | 57 | 58 | 59 | true 60 | standalone 61 | 62 | 64 | 66 | 68 | 70 | META-INF/spring.handlers 71 | 72 | 74 | META-INF/spring.schemas 75 | 76 | 78 | META-INF/spring.tooling 79 | 80 | 82 | META-INF/spring.factories 83 | 84 | 86 | META-INF/cxf/bus-extensions.txt 87 | 88 | 90 | META-INF/mime.types 91 | 92 | 94 | jasperreports_extension.properties 95 | 96 | 98 | ValidationMessages.*\\.properties 99 | 100 | 102 | META-INF/web-fragment.xml 103 | 104 | 106 | META-INF/web/web-fragment.xml 107 | 108 | 110 | META-INF/aop.xml 111 | 112 | 114 | META-INF/wsdl.plugin.xml 115 | 116 | 117 | 118 | 119 | *:* 120 | 121 | META-INF/*.SF 122 | META-INF/*.DSA 123 | META-INF/*.RSA 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument-burningwave/src/main/java/burningwave.static.properties: -------------------------------------------------------------------------------- 1 | banner.hide=true 2 | managed-logger.repository.enabled=false 3 | #avoiding the automatic call on startup of Burningwave Core to method 4 | #org.burningwave.core.assembler.StaticComponentContainer.Modules.exportAllToAll() 5 | #which exports all modules to all modules 6 | modules.export-all-to-all=false 7 | #prevent threads from spawning unnecessarily: https://github.com/burningwave/core/issues/10 8 | background-executor.all-tasks-monitoring.enabled=false 9 | static-component-container.on-close.close-all-component-containers=false 10 | static-component-container.on-close.close-file-system-helper=false -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument-burningwave/src/main/java/de/invesdwin/instrument/burningwave/BurningwaveInstrumentationAgent.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.burningwave; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | 5 | import org.burningwave.core.assembler.StaticComponentContainer; 6 | 7 | // @Immutable 8 | public final class BurningwaveInstrumentationAgent { 9 | 10 | private BurningwaveInstrumentationAgent() {} 11 | 12 | public static void premain(final String args, final Instrumentation inst) throws Exception { 13 | StaticComponentContainer.Modules.exportAllToAll(); 14 | } 15 | 16 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 17 | premain(args, inst); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/.gitignore: -------------------------------------------------------------------------------- 1 | /.checkstyle 2 | /.classpath 3 | /log 4 | /target 5 | /activemq-data 6 | /.fbprefs 7 | /cache 8 | /.settings 9 | /.project 10 | /*.hprof 11 | /.jrctemp 12 | /.invesdwin 13 | /nbproject 14 | /bin 15 | /.springBeans 16 | /.factorypath 17 | /.attach_pid* 18 | /**/.DS_Store 19 | /.idea 20 | /**/*.iml 21 | /.sessions 22 | /**/.~lock.* 23 | /.pydevproject 24 | /Report_*.java 25 | /octave-workspace 26 | /hs_err_pid*.log 27 | /*.Rout 28 | /.apt* 29 | /ajcore.*.txt 30 | /.temp-*.txt 31 | /dependency-reduced-pom.xml 32 | /META-INF 33 | /.Rproj.user 34 | /.Rhistory 35 | /.RData 36 | /.Ruserdata 37 | /.vite 38 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | de.invesdwin 5 | invesdwin-instrument-parent 6 | 1.0.15-SNAPSHOT 7 | 8 | invesdwin-instrument 9 | jar 10 | 11 | 12 | 13 | commons-io 14 | commons-io 15 | 16 | 17 | com.google.code.findbugs 18 | jsr305 19 | 20 | 21 | org.springframework 22 | spring-context 23 | 24 | 25 | org.springframework 26 | spring-core 27 | 28 | 29 | org.slf4j 30 | jcl-over-slf4j 31 | 32 | 33 | org.springframework 34 | spring-instrument 35 | 36 | 37 | org.aspectj 38 | aspectjweaver 39 | 40 | 41 | org.zeroturnaround 42 | zt-exec 43 | 44 | 45 | org.slf4j 46 | slf4j-simple 47 | test 48 | 49 | 50 | com.github.olivergondza 51 | maven-jdk-tools-wrapper 52 | ${version.maven-jdk-tools-wrapper} 53 | provided 54 | 55 | 56 | 57 | org.junit.jupiter 58 | junit-jupiter-engine 59 | test 60 | 61 | 62 | org.junit.platform 63 | junit-platform-suite-engine 64 | test 65 | 66 | 67 | org.burningwave 68 | core 69 | test 70 | 71 | 72 | 73 | 74 | 75 | 76 | org.apache.maven.plugins 77 | maven-jar-plugin 78 | 79 | 80 | 81 | de.invesdwin.instrument.internal.DynamicInstrumentationAgent 82 | de.invesdwin.instrument.internal.DynamicInstrumentationAgent 83 | true 84 | true 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/META-INF/ctx.spring.weaving.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/DynamicInstrumentationLoader.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument; 2 | 3 | import java.io.EOFException; 4 | import java.io.File; 5 | import java.io.FileOutputStream; 6 | import java.io.InputStream; 7 | import java.lang.reflect.Method; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.concurrent.TimeUnit; 11 | import java.util.concurrent.TimeoutException; 12 | import java.util.jar.JarEntry; 13 | import java.util.jar.JarOutputStream; 14 | import java.util.jar.Manifest; 15 | 16 | import javax.annotation.concurrent.ThreadSafe; 17 | 18 | import org.apache.commons.io.IOUtils; 19 | import org.springframework.context.support.GenericXmlApplicationContext; 20 | import org.springframework.core.io.ClassPathResource; 21 | import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver; 22 | import org.zeroturnaround.exec.ProcessExecutor; 23 | import org.zeroturnaround.exec.stream.slf4j.Slf4jStream; 24 | 25 | import de.invesdwin.instrument.internal.AgentClassLoaderReference; 26 | import de.invesdwin.instrument.internal.DynamicInstrumentationAgent; 27 | import de.invesdwin.instrument.internal.DynamicInstrumentationAgentCompiler; 28 | import de.invesdwin.instrument.internal.DynamicInstrumentationLoadAgentMain; 29 | import de.invesdwin.instrument.internal.JdkFilesFinder; 30 | import de.invesdwin.instrument.internal.compile.DynamicInstrumentationClassInfo; 31 | 32 | @ThreadSafe 33 | public final class DynamicInstrumentationLoader { 34 | 35 | private static volatile Throwable threadFailed; 36 | private static volatile String toolsJarPath; 37 | private static volatile String attachLibPath; 38 | /** 39 | * keeping a reference here so it is not garbage collected 40 | */ 41 | private static GenericXmlApplicationContext ltwCtx; 42 | 43 | private DynamicInstrumentationLoader() {} 44 | 45 | public static boolean isInitialized() { 46 | return InstrumentationLoadTimeWeaver.isInstrumentationAvailable(); 47 | } 48 | 49 | public static void waitForInitialized() { 50 | try { 51 | while (!isInitialized() && threadFailed == null) { 52 | TimeUnit.MILLISECONDS.sleep(1); 53 | } 54 | if (threadFailed != null) { 55 | final String javaVersion = getJavaVersion(); 56 | final String javaHome = getJavaHome(); 57 | throw new RuntimeException("Additional information: javaVersion=" + javaVersion + "; javaHome=" 58 | + javaHome + "; toolsJarPath=" + toolsJarPath + "; attachLibPath=" + attachLibPath, 59 | threadFailed); 60 | } 61 | } catch (final InterruptedException e) { 62 | Thread.currentThread().interrupt(); 63 | } 64 | } 65 | 66 | public static synchronized GenericXmlApplicationContext initLoadTimeWeavingContext() { 67 | if (!isInitialized()) { 68 | throw new IllegalStateException("Should be initialized"); 69 | } 70 | if (ltwCtx == null) { 71 | final GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(); 72 | ctx.load(new ClassPathResource("/META-INF/ctx.spring.weaving.xml")); 73 | ctx.refresh(); 74 | ltwCtx = ctx; 75 | } 76 | return ltwCtx; 77 | } 78 | 79 | static { 80 | if (!isInitialized()) { 81 | initialize(); 82 | } 83 | } 84 | 85 | private static void initialize() { 86 | try { 87 | String uuid = null; 88 | File tempAgentJar = null; 89 | 90 | //first try a precompiled agent, since lombok might cause exceptions during compilation 91 | addAgentClassLoaderReferenceToSystemClassLoader(); 92 | uuid = nextPrecompiledUuid(); 93 | if (uuid != null) { 94 | try { 95 | tempAgentJar = createPrecompiledTempAgentJar(uuid); 96 | } catch (final Throwable t) { 97 | //CHECKSTYLE:OFF 98 | new RuntimeException("Ignoring: Error loading precompiled agent, falling back to compiled ...", t) 99 | .printStackTrace(); 100 | //CHECKSYLE:ON 101 | uuid = null; 102 | tempAgentJar = null; 103 | } 104 | } 105 | if (uuid == null) { 106 | uuid = DynamicInstrumentationAgentCompiler.nextCompileUuid(); 107 | if (uuid != null) { 108 | try { 109 | tempAgentJar = createCompiledTempAgentJar(uuid); 110 | } catch (final Throwable t) { 111 | //CHECKSTYLE:OFF 112 | new RuntimeException("Ignoring: Error loading compiled agent, falling back to default ...", t) 113 | .printStackTrace(); 114 | //CHECKSTYLE:ON 115 | uuid = null; 116 | tempAgentJar = null; 117 | } 118 | } 119 | } 120 | if (uuid == null) { 121 | uuid = DynamicInstrumentationAgent.DEFAULT_UUID; 122 | tempAgentJar = createDefaultTempAgentJar(null); 123 | } 124 | 125 | setAgentClassLoaderReference(uuid); 126 | final String pid = DynamicInstrumentationProperties.getProcessId(); 127 | final File finalTempAgentJar = tempAgentJar; 128 | final String finalUuid = uuid; 129 | final Thread loadAgentThread = new Thread() { 130 | 131 | @Override 132 | public void run() { 133 | try { 134 | loadAgent(finalTempAgentJar, pid, finalUuid); 135 | } catch (final Throwable e) { 136 | threadFailed = e; 137 | throw new RuntimeException(e); 138 | } 139 | } 140 | }; 141 | 142 | DynamicInstrumentationReflections.addPathToSystemClassLoader(tempAgentJar); 143 | 144 | final JdkFilesFinder jdkFilesFinder = new JdkFilesFinder(); 145 | 146 | if (DynamicInstrumentationReflections.isBeforeJava9()) { 147 | final File toolsJar = jdkFilesFinder.findToolsJar(); 148 | DynamicInstrumentationReflections.addPathToSystemClassLoader(toolsJar); 149 | DynamicInstrumentationLoader.toolsJarPath = toolsJar.getAbsolutePath(); 150 | 151 | final File attachLib = jdkFilesFinder.findAttachLib(); 152 | DynamicInstrumentationReflections.addPathToJavaLibraryPath(attachLib.getParentFile()); 153 | DynamicInstrumentationLoader.attachLibPath = attachLib.getAbsolutePath(); 154 | } 155 | 156 | loadAgentThread.start(); 157 | } catch (final Exception e) { 158 | throw new RuntimeException("Final exception during agent loading:", e); 159 | } 160 | } 161 | 162 | private static String nextPrecompiledUuid() throws Exception { 163 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 164 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 165 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 166 | .loadClass(agentClassLoaderReferenceClass.getName()); 167 | final Method nextPrecompiledUuidMethod = systemAgentClassLoaderReferenceClass 168 | .getDeclaredMethod("nextPrecompiledUuid"); 169 | final String nextPrecompiledUuid = (String) nextPrecompiledUuidMethod.invoke(null); 170 | return nextPrecompiledUuid; 171 | } 172 | 173 | private static void addAgentClassLoaderReferenceToSystemClassLoader() throws Exception { 174 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 175 | final ClassLoader systemClassLoader = DynamicInstrumentationReflections.getSystemClassLoader(); 176 | final long startNanos = System.nanoTime(); 177 | final long timeoutNanos = TimeUnit.NANOSECONDS.convert(5, TimeUnit.SECONDS); 178 | while (!hasAgentClassLoaderReferenceInSystemClassLoader(agentClassLoaderReferenceClass, systemClassLoader)) { 179 | final File tempAgentClassLoaderJar = createTempJar(agentClassLoaderReferenceClass, null, false, false); 180 | //will be null when another thread has already created the jar 181 | if (tempAgentClassLoaderJar != null) { 182 | DynamicInstrumentationReflections.addPathToSystemClassLoader(tempAgentClassLoaderJar); 183 | } else { 184 | //wait for other thread to finish adding the class to the system class loader 185 | TimeUnit.MILLISECONDS.sleep(100); 186 | } 187 | if (System.nanoTime() - startNanos > timeoutNanos) { 188 | throw new TimeoutException("Unable to load " + agentClassLoaderReferenceClass.getSimpleName() 189 | + " into system class loader"); 190 | } 191 | } 192 | } 193 | 194 | private static boolean hasAgentClassLoaderReferenceInSystemClassLoader( 195 | final Class agentClassLoaderReferenceClass, 196 | final ClassLoader systemClassLoader) { 197 | try { 198 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 199 | .loadClass(agentClassLoaderReferenceClass.getName()); 200 | return systemAgentClassLoaderReferenceClass != null; 201 | } catch (final ClassNotFoundException e) { 202 | return false; 203 | } 204 | } 205 | 206 | private static void loadAgent(final File tempAgentJar, final String pid, final String uuid) throws Exception { 207 | if (DynamicInstrumentationReflections.isBeforeJava9()) { 208 | DynamicInstrumentationLoadAgentMain.loadAgent(pid, tempAgentJar.getAbsolutePath()); 209 | } else { 210 | //-Djdk.attach.allowAttachSelf https://www.bountysource.com/issues/45231289-self-attach-fails-on-jdk9 211 | //workaround this limitation by attaching from a new process 212 | final File loadAgentJar = createTempJar(DynamicInstrumentationLoadAgentMain.class, uuid, false, true, 213 | de.invesdwin.instrument.internal.DummyAttachProvider.class); 214 | final String javaExecutable = getJavaHome() + File.separator + "bin" + File.separator + "java"; 215 | final List command = new ArrayList(); 216 | command.add(javaExecutable); 217 | command.add("-classpath"); 218 | command.add(loadAgentJar.getAbsolutePath()); //tools.jar not needed since java9 219 | command.add(DynamicInstrumentationLoadAgentMain.class.getName()); 220 | command.add(pid); 221 | command.add(tempAgentJar.getAbsolutePath()); 222 | new ProcessExecutor().command(command) 223 | .destroyOnExit() 224 | .exitValueNormal() 225 | .redirectOutput(Slf4jStream.of(DynamicInstrumentationLoader.class).asInfo()) 226 | .redirectError(Slf4jStream.of(DynamicInstrumentationLoader.class).asWarn()) 227 | .execute(); 228 | } 229 | } 230 | 231 | private static String getJavaHome() { 232 | //CHECKSTYLE:OFF 233 | return System.getProperty("java.home"); 234 | //CHECKSTYLE:ON 235 | } 236 | 237 | private static String getJavaVersion() { 238 | //CHECKSTYLE:OFF 239 | return System.getProperty("java.version"); 240 | //CHECKSTYLE:ON 241 | } 242 | 243 | private static void setAgentClassLoaderReference(final String uuid) throws Exception { 244 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 245 | final ClassLoader systemClassLoader = DynamicInstrumentationReflections.getSystemClassLoader(); 246 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 247 | .loadClass(agentClassLoaderReferenceClass.getName()); 248 | 249 | final Method containsAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 250 | .getDeclaredMethod("containsAgentClassLoader", String.class); 251 | final boolean containsAgentClassLoader = (boolean) containsAgentClassLoaderMethod.invoke(null, uuid); 252 | if (containsAgentClassLoader) { 253 | throw new IllegalStateException("UUID already used: " + uuid); 254 | } 255 | 256 | final Method setAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 257 | .getDeclaredMethod("setAgentClassLoader", String.class, ClassLoader.class); 258 | final ClassLoader contextClassLoader = DynamicInstrumentationReflections.getContextClassLoader(); 259 | setAgentClassLoaderMethod.invoke(null, uuid, contextClassLoader); 260 | } 261 | 262 | private static File createDefaultTempAgentJar(final String uuid) throws ClassNotFoundException { 263 | try { 264 | return createTempJar(DynamicInstrumentationAgent.class, uuid, true, true); 265 | } catch (final Throwable e) { 266 | throw newClassNotFoundException( 267 | "de.invesdwin.instrument.internal.DynamicInstrumentationAgent_" + uuid + ".class", e); 268 | } 269 | } 270 | 271 | private static File createPrecompiledTempAgentJar(final String uuid) throws ClassNotFoundException { 272 | try { 273 | final DynamicInstrumentationClassInfo classInfo = DynamicInstrumentationAgentCompiler.precompiled(uuid); 274 | final String className = classInfo.toString(); 275 | try (InputStream classIn = classInfo.newInputStream()) { 276 | return createTempJar(className, classIn, uuid, true, true); 277 | } 278 | } catch (final Throwable e) { 279 | throw newClassNotFoundException( 280 | "de.invesdwin.instrument.internal.DynamicInstrumentationAgent_" + uuid + ".class", e); 281 | } 282 | } 283 | 284 | private static ClassNotFoundException newClassNotFoundException(final String file, final Throwable e) { 285 | final String message = "Unable to find file [" + file + "] in classpath." 286 | + "\nPlease make sure you have added invesdwin-instrument.jar to your classpath properly," 287 | + "\nor make sure you have embedded it correctly into your fat-jar." 288 | + "\nThey can be created e.g. with \"maven-shade-plugin\"." 289 | + "\nPlease be aware that some fat-jar solutions might not work well due to classloader issues: " 290 | + e.toString(); 291 | return new ClassNotFoundException(message, e); 292 | } 293 | 294 | private static File createCompiledTempAgentJar(final String uuid) throws ClassNotFoundException { 295 | try { 296 | final DynamicInstrumentationClassInfo classInfo = DynamicInstrumentationAgentCompiler.compile(uuid); 297 | final String className = classInfo.toString(); 298 | try (InputStream classIn = classInfo.newInputStream()) { 299 | return createTempJar(className, classIn, uuid, true, true); 300 | } 301 | } catch (final Throwable e) { 302 | throw newClassNotFoundException( 303 | "de.invesdwin.instrument.internal.DynamicInstrumentationAgent_" + uuid + ".class", e); 304 | } 305 | } 306 | 307 | private static File createTempJar(final Class clazz, final String uuid, final boolean agent, 308 | final boolean overwrite, final Class... additionalClasses) throws Exception { 309 | try { 310 | final String className = clazz.getName(); 311 | try (InputStream classIn = DynamicInstrumentationReflections.getClassInputStream(clazz)) { 312 | return createTempJar(className, classIn, uuid, agent, overwrite, additionalClasses); 313 | } 314 | } catch (final Throwable e) { 315 | throw newClassNotFoundException(clazz.getName() + ".class", e); 316 | } 317 | } 318 | 319 | /** 320 | * Creates a new jar that only contains the DynamicInstrumentationAgent class. 321 | */ 322 | private static File createTempJar(final String className, final InputStream classIn, final String uuid, 323 | final boolean agent, final boolean overwrite, final Class... additionalClasses) throws Exception { 324 | final StringBuilder fileName = new StringBuilder(className); 325 | if (uuid != null) { 326 | fileName.append("_"); 327 | fileName.append(uuid); 328 | } 329 | fileName.append(".jar"); 330 | final File tempAgentJar = new File(DynamicInstrumentationProperties.PROCESS_TEMP_DIRECTORY, fileName.toString()); 331 | if (!overwrite && tempAgentJar.exists()) { 332 | return null; 333 | } 334 | final Manifest manifest = new Manifest( 335 | DynamicInstrumentationLoader.class.getResourceAsStream("/META-INF/MANIFEST.MF")); 336 | if (agent) { 337 | manifest.getMainAttributes().putValue("Premain-Class", className); 338 | manifest.getMainAttributes().putValue("Agent-Class", className); 339 | manifest.getMainAttributes().putValue("Can-Redefine-Classes", String.valueOf(true)); 340 | manifest.getMainAttributes().putValue("Can-Retransform-Classes", String.valueOf(true)); 341 | } 342 | final JarOutputStream tempJarOut = new JarOutputStream(new FileOutputStream(tempAgentJar), manifest); 343 | final JarEntry entry = new JarEntry(className.replace(".", "/") + ".class"); 344 | tempJarOut.putNextEntry(entry); 345 | try { 346 | IOUtils.copy(classIn, tempJarOut); 347 | } catch (final EOFException e) { 348 | //ignore, can happen in MpjExpress 349 | } 350 | tempJarOut.closeEntry(); 351 | if (additionalClasses != null) { 352 | for (final Class additionalClazz : additionalClasses) { 353 | final String additionalClassName = additionalClazz.getName(); 354 | final JarEntry additionalEntry = new JarEntry(additionalClassName.replace(".", "/") + ".class"); 355 | tempJarOut.putNextEntry(additionalEntry); 356 | final InputStream additionalClassIn = DynamicInstrumentationReflections 357 | .getClassInputStream(additionalClazz); 358 | IOUtils.copy(additionalClassIn, tempJarOut); 359 | tempJarOut.closeEntry(); 360 | } 361 | } 362 | tempJarOut.close(); 363 | return tempAgentJar; 364 | } 365 | 366 | } 367 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/DynamicInstrumentationProperties.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.lang.management.ManagementFactory; 6 | import java.util.concurrent.ThreadLocalRandom; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | import javax.annotation.concurrent.Immutable; 10 | 11 | @Immutable 12 | public final class DynamicInstrumentationProperties { 13 | 14 | public static final File SYSTEM_TEMP_DIRECTORY; 15 | /** 16 | * Process specific temp dir that gets cleaned on exit. 17 | */ 18 | public static final File USER_TEMP_DIRECTORY; 19 | public static final File PROCESS_TEMP_DIRECTORY; 20 | public static final String USER_TEMP_DIRECTORY_NAME; 21 | private static Runnable deleteTempDirectoryRunner = new Runnable() { 22 | @Override 23 | public void run() { 24 | org.apache.commons.io.FileUtils.deleteQuietly(PROCESS_TEMP_DIRECTORY); 25 | } 26 | }; 27 | 28 | static { 29 | //CHECKSTYLE:OFF 30 | String systemTempDir = System 31 | .getProperty(DynamicInstrumentationProperties.class.getName() + ".TEMP_DIRECTORY_OVERRIDE"); 32 | if (systemTempDir == null) { 33 | systemTempDir = System.getProperty("java.io.tmpdir"); 34 | } 35 | SYSTEM_TEMP_DIRECTORY = new File(systemTempDir); 36 | final String username = System.getProperty("user.name"); 37 | //CHECKSTYLE:ON 38 | /* 39 | * we can not use a shared "invesdwin" folder for all users because permissions would hinder one user from 40 | * creating another folder in the invesdwin folder, so use a flat structure instead 41 | */ 42 | USER_TEMP_DIRECTORY_NAME = "invesdwin_temp_" + username.replaceAll("[^a-zA-Z0-9]", ""); 43 | USER_TEMP_DIRECTORY = new File(SYSTEM_TEMP_DIRECTORY, USER_TEMP_DIRECTORY_NAME); 44 | PROCESS_TEMP_DIRECTORY = newProcessTempDirectory(USER_TEMP_DIRECTORY); 45 | } 46 | 47 | private DynamicInstrumentationProperties() {} 48 | 49 | public static File newProcessTempDirectory(final File baseDirectory) { 50 | final File tempDir = findEmptyTempDir(baseDirectory); 51 | forceMkdirRetry(baseDirectory, tempDir); 52 | Runtime.getRuntime().addShutdownHook(new Thread() { 53 | @Override 54 | public void run() { 55 | deleteTempDirectoryRunner.run(); 56 | } 57 | }); 58 | return tempDir; 59 | } 60 | 61 | private static void forceMkdirRetry(final File baseDirectory, final File tempDir) { 62 | final ThreadLocalRandom random = ThreadLocalRandom.current(); 63 | final int maxTries = 3; 64 | IOException lastException = null; 65 | for (int tries = 0; tries < maxTries; tries++) { 66 | try { 67 | lastException = null; 68 | org.apache.commons.io.FileUtils.forceMkdir(tempDir); 69 | baseDirectory.setWritable(true, false); 70 | } catch (final IOException e) { 71 | lastException = e; 72 | try { 73 | TimeUnit.MILLISECONDS.sleep(random.nextLong(100)); 74 | } catch (final InterruptedException e1) { 75 | throw new RuntimeException(e1); 76 | } 77 | } 78 | } 79 | if (lastException != null) { 80 | throw new RuntimeException(lastException); 81 | } 82 | } 83 | 84 | public static void setDeleteTempDirectoryRunner(final Runnable deleteTempDirectoryRunner) { 85 | if (deleteTempDirectoryRunner == null) { 86 | throw new NullPointerException(); 87 | } 88 | DynamicInstrumentationProperties.deleteTempDirectoryRunner = deleteTempDirectoryRunner; 89 | } 90 | 91 | private static File findEmptyTempDir(final File baseDirectory) { 92 | File tempDir = new File(baseDirectory, ManagementFactory.getRuntimeMXBean().getName()); 93 | int retry = 0; 94 | while (tempDir.exists() && !org.apache.commons.io.FileUtils.deleteQuietly(tempDir)) { 95 | //no permission to delete folder (maybe different user had this pid before), choose a different one 96 | tempDir = new File(tempDir.getAbsolutePath() + "_" + retry); 97 | retry++; 98 | } 99 | return tempDir; 100 | } 101 | 102 | public static String getProcessId() { 103 | final String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName(); 104 | final String pid = nameOfRunningVM.substring(0, nameOfRunningVM.indexOf('@')); 105 | return pid; 106 | } 107 | 108 | public static String getProcessName() { 109 | final String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName(); 110 | final String name = nameOfRunningVM.substring(nameOfRunningVM.indexOf('@') + 1, nameOfRunningVM.length()); 111 | return name; 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/DynamicInstrumentationReflections.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument; 2 | 3 | import java.io.File; 4 | import java.io.InputStream; 5 | import java.lang.instrument.Instrumentation; 6 | import java.lang.reflect.Field; 7 | import java.lang.reflect.InvocationTargetException; 8 | import java.lang.reflect.Method; 9 | import java.lang.reflect.Modifier; 10 | import java.net.MalformedURLException; 11 | import java.net.URL; 12 | import java.net.URLClassLoader; 13 | import java.util.ArrayDeque; 14 | import java.util.ArrayList; 15 | import java.util.HashSet; 16 | import java.util.Set; 17 | import java.util.Stack; 18 | 19 | import javax.annotation.concurrent.Immutable; 20 | 21 | import org.apache.commons.io.FilenameUtils; 22 | import org.springframework.instrument.InstrumentationSavingAgent; 23 | 24 | import de.invesdwin.instrument.internal.RemoveFinalModifierJava9; 25 | 26 | @Immutable 27 | public final class DynamicInstrumentationReflections { 28 | 29 | private static final URL[] EMPTY_URLS = new URL[0]; 30 | private static Set pathsAddedToSystemClassLoader = java.util.Collections 31 | .synchronizedSet(new HashSet()); 32 | 33 | private DynamicInstrumentationReflections() {} 34 | 35 | @SuppressWarnings({ "restriction", "unchecked" }) 36 | public static URL[] getURLs(final ClassLoader classLoader) { 37 | if (classLoader == null) { 38 | throw new NullPointerException("classLoader should not be null"); 39 | } 40 | 41 | if (classLoader instanceof URLClassLoader) { 42 | //java 8 and below 43 | return ((URLClassLoader) classLoader).getURLs(); 44 | } 45 | 46 | // jdk9 or above 47 | try { 48 | //normal way: --add-opens java.base/jdk.internal.loader=ALL-UNNAMED 49 | //hacker way: https://javax0.wordpress.com/2017/05/03/hacking-the-integercache-in-java-9/ 50 | final sun.misc.Unsafe unsafe = getUnsafe(); 51 | //jdk.internal.loader.ClassLoaders.AppClassLoader.ucp 52 | final Field ucpField = getField(classLoader.getClass(), "ucp"); 53 | final Object ucp = unsafe.getObject(classLoader, unsafe.objectFieldOffset(ucpField)); 54 | 55 | //jdk.internal.loader.URLClassPath.addUrl(...) 56 | synchronized (ucp) { 57 | final Field pathField = ucp.getClass().getDeclaredField("path"); 58 | final ArrayList path = (ArrayList) unsafe.getObject(ucp, unsafe.objectFieldOffset(pathField)); 59 | return path.toArray(EMPTY_URLS); 60 | } 61 | } catch (final NoSuchFieldException e) { 62 | throw new RuntimeException(classLoader.getClass().getName(), e); 63 | } 64 | } 65 | 66 | /** 67 | * http://stackoverflow.com/questions/1010919/adding-files-to-java-classpath-at-runtime 68 | */ 69 | public static void addPathToSystemClassLoader(final File dirOrJar) { 70 | if (dirOrJar == null) { 71 | return; 72 | } 73 | final ClassLoader systemClassLoader = getSystemClassLoader(); 74 | try { 75 | final String normalizedPath = FilenameUtils.normalize(dirOrJar.getAbsolutePath()); 76 | if (!pathsAddedToSystemClassLoader.add(normalizedPath)) { 77 | throw new IllegalStateException("Path [" + normalizedPath + "] has already been added before!"); 78 | } 79 | final URL url = new File(normalizedPath).toURI().toURL(); 80 | if (isBeforeJava9()) { 81 | addUrlToURLClassLoader(systemClassLoader, url); 82 | } else { 83 | //we are in java 9 or above 84 | addUrlToAppClassLoaderURLClassPath(systemClassLoader, url); 85 | } 86 | } catch (final NoSuchMethodException e) { 87 | org.springframework.util.ReflectionUtils.handleReflectionException(e); 88 | } catch (final SecurityException e) { 89 | org.springframework.util.ReflectionUtils.handleReflectionException(e); 90 | } catch (final IllegalAccessException e) { 91 | org.springframework.util.ReflectionUtils.handleReflectionException(e); 92 | } catch (final IllegalArgumentException e) { 93 | org.springframework.util.ReflectionUtils.handleReflectionException(e); 94 | } catch (final MalformedURLException e) { 95 | org.springframework.util.ReflectionUtils.handleReflectionException(e); 96 | } catch (final InvocationTargetException e) { 97 | org.springframework.util.ReflectionUtils.handleReflectionException(e); 98 | } catch (final NoSuchFieldException e) { 99 | throw new RuntimeException(systemClassLoader.getClass().getName(), e); 100 | } 101 | } 102 | 103 | public static boolean isBeforeJava9() { 104 | return getSystemClassLoader() instanceof URLClassLoader; 105 | } 106 | 107 | private static void addUrlToURLClassLoader(final ClassLoader systemClassLoader, final URL url) 108 | throws NoSuchMethodException, MalformedURLException, IllegalAccessException, InvocationTargetException { 109 | final Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); 110 | method.setAccessible(true); 111 | method.invoke(systemClassLoader, url); 112 | } 113 | 114 | private static Field getField(final Class startClazz, final String fieldName) throws NoSuchFieldException { 115 | Field field = null; 116 | Class clazz = startClazz; 117 | do { 118 | try { 119 | field = clazz.getDeclaredField(fieldName); 120 | } catch (final NoSuchFieldException e) { 121 | clazz = clazz.getSuperclass(); 122 | if (clazz == null) { 123 | throw e; 124 | } 125 | } 126 | } while (field == null); 127 | return field; 128 | } 129 | 130 | @SuppressWarnings({ "unchecked", "restriction" }) 131 | private static void addUrlToAppClassLoaderURLClassPath(final ClassLoader systemClassLoader, final URL url) 132 | throws NoSuchFieldException, SecurityException { 133 | //normal way: --add-opens java.base/jdk.internal.loader=ALL-UNNAMED 134 | //hacker way: https://javax0.wordpress.com/2017/05/03/hacking-the-integercache-in-java-9/ 135 | final sun.misc.Unsafe unsafe = getUnsafe(); 136 | //jdk.internal.loader.ClassLoaders.AppClassLoader.ucp 137 | final Field ucpField = getField(systemClassLoader.getClass(), "ucp"); 138 | final Object ucp = unsafe.getObject(systemClassLoader, unsafe.objectFieldOffset(ucpField)); 139 | 140 | //jdk.internal.loader.URLClassPath.addUrl(...) 141 | synchronized (ucp) { 142 | final Field pathField = ucp.getClass().getDeclaredField("path"); 143 | final ArrayList path = (ArrayList) unsafe.getObject(ucp, unsafe.objectFieldOffset(pathField)); 144 | 145 | try { 146 | //java 11 and up 147 | final Field urlsField = ucp.getClass().getDeclaredField("unopenedUrls"); 148 | final ArrayDeque urls = (ArrayDeque) unsafe.getObject(ucp, 149 | unsafe.objectFieldOffset(urlsField)); 150 | synchronized (urls) { 151 | if (url == null || path.contains(url)) { 152 | return; 153 | } 154 | urls.addFirst(url); 155 | path.add(url); 156 | } 157 | } catch (final NoSuchFieldException e) { 158 | //java 9 and 10 159 | final Field urlsField = ucp.getClass().getDeclaredField("urls"); 160 | final Stack urls = (Stack) unsafe.getObject(ucp, unsafe.objectFieldOffset(urlsField)); 161 | synchronized (urls) { 162 | if (url == null || path.contains(url)) { 163 | return; 164 | } 165 | urls.add(0, url); 166 | path.add(url); 167 | } 168 | } 169 | } 170 | } 171 | 172 | @SuppressWarnings("restriction") 173 | public static sun.misc.Unsafe getUnsafe() { 174 | try { 175 | final Field unsafeField = sun.misc.Unsafe.class.getDeclaredField("theUnsafe"); 176 | unsafeField.setAccessible(true); 177 | final sun.misc.Unsafe unsafe = (sun.misc.Unsafe) unsafeField.get(null); 178 | return unsafe; 179 | } catch (final Throwable e) { 180 | throw new RuntimeException(e); 181 | } 182 | } 183 | 184 | public static ClassLoader getContextClassLoader() { 185 | return Thread.currentThread().getContextClassLoader(); 186 | } 187 | 188 | public static ClassLoader getSystemClassLoader() { 189 | return ClassLoader.getSystemClassLoader(); 190 | } 191 | 192 | public static Set getPathsAddedToSystemClassLoader() { 193 | return java.util.Collections.unmodifiableSet(pathsAddedToSystemClassLoader); 194 | } 195 | 196 | /** 197 | * http://stackoverflow.com/questions/11134159/how-to-load-attachprovider-attach-dll-dynamically 198 | * 199 | * https://stackoverflow.com/a/70126075 200 | */ 201 | public static void addPathToJavaLibraryPath(final File dir) { 202 | if (dir == null) { 203 | return; 204 | } 205 | final String javaLibraryPathKey = "java.library.path"; 206 | //CHECKSTYLE:OFF 207 | final String existingJavaLibraryPath = System.getProperty(javaLibraryPathKey); 208 | //CHECKSTYLE:ON 209 | final String newJavaLibraryPath; 210 | if (!org.springframework.util.StringUtils.hasLength(existingJavaLibraryPath)) { 211 | newJavaLibraryPath = existingJavaLibraryPath + File.pathSeparator + dir.getAbsolutePath(); 212 | } else { 213 | newJavaLibraryPath = dir.getAbsolutePath(); 214 | } 215 | //CHECKSTYLE:OFF 216 | System.setProperty(javaLibraryPathKey, newJavaLibraryPath); 217 | //CHECKSTYLE:ON 218 | try { 219 | final Class nativeLibrariesClass = Class.forName("jdk.internal.loader.NativeLibraries"); 220 | final Class[] declClassArr = nativeLibrariesClass.getDeclaredClasses(); 221 | final Class libraryPaths = java.util.Arrays.stream(declClassArr) 222 | .filter(klass -> klass.getSimpleName().equals("LibraryPaths")) 223 | .findFirst() 224 | .get(); 225 | final Field field = libraryPaths.getDeclaredField("USER_PATHS"); 226 | field.setAccessible(true); 227 | removeFinalModifier(field); 228 | 229 | final String[] paths = (String[]) field.get(null); 230 | final String[] newPaths = new String[paths.length + 1]; 231 | for (int i = 0; i < paths.length; i++) { 232 | newPaths[i] = paths[i]; 233 | } 234 | newPaths[newPaths.length - 1] = dir.getAbsolutePath(); 235 | field.set(null, newPaths); 236 | } catch (final NoSuchFieldException | ClassNotFoundException e) { 237 | //retry different approach, this might happen on older JVMs 238 | addPathToJavaLibraryPathJavaOld(); 239 | } catch (final SecurityException e) { 240 | throw new RuntimeException(e); 241 | } catch (final IllegalAccessException e) { 242 | throw new RuntimeException(e); 243 | } 244 | } 245 | 246 | public static void removeFinalModifier(final Field field) throws IllegalAccessException, NoSuchFieldException { 247 | try { 248 | RemoveFinalModifierJava9.removeFinalModifierJava9(field); 249 | } catch (final Throwable t) { 250 | //fallback to how this was done in java 8 251 | final Field modifiersField = Field.class.getDeclaredField("modifiers"); 252 | modifiersField.setAccessible(true); 253 | modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); 254 | } 255 | 256 | } 257 | 258 | private static void addPathToJavaLibraryPathJavaOld() { 259 | try { 260 | final Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); 261 | fieldSysPath.setAccessible(true); 262 | fieldSysPath.set(ClassLoader.class, null); 263 | } catch (final NoSuchFieldException e) { 264 | /* 265 | * ignore, happens on ibm-jdk-8 and adoptopenjdk-8-openj9 but has no influence since there is no cached 266 | * field that needs a reset 267 | */ 268 | return; 269 | } catch (final SecurityException e) { 270 | org.springframework.util.ReflectionUtils.handleReflectionException(e); 271 | } catch (final IllegalArgumentException e) { 272 | org.springframework.util.ReflectionUtils.handleReflectionException(e); 273 | } catch (final IllegalAccessException e) { 274 | org.springframework.util.ReflectionUtils.handleReflectionException(e); 275 | } 276 | try { 277 | final Method methodInitLibraryPaths = ClassLoader.class.getDeclaredMethod("initLibraryPaths"); 278 | methodInitLibraryPaths.setAccessible(true); 279 | methodInitLibraryPaths.invoke(ClassLoader.class); 280 | } catch (final NoSuchMethodException e) { 281 | //ignore, this might happen on older JVMs 282 | } catch (final SecurityException e) { 283 | org.springframework.util.ReflectionUtils.handleReflectionException(e); 284 | } catch (final IllegalAccessException e) { 285 | org.springframework.util.ReflectionUtils.handleReflectionException(e); 286 | } catch (final IllegalArgumentException e) { 287 | org.springframework.util.ReflectionUtils.handleReflectionException(e); 288 | } catch (final InvocationTargetException e) { 289 | org.springframework.util.ReflectionUtils.handleReflectionException(e); 290 | } 291 | } 292 | 293 | public static InputStream getClassInputStream(final Class clazz) throws ClassNotFoundException { 294 | final String name = "/" + clazz.getName().replace(".", "/") + ".class"; 295 | final InputStream classIn = clazz.getResourceAsStream(name); 296 | if (classIn == null) { 297 | throw new NullPointerException("resource input stream should not be null: " + name); 298 | } 299 | return classIn; 300 | } 301 | 302 | public static Instrumentation getInstrumentation() { 303 | return InstrumentationSavingAgent.getInstrumentation(); 304 | } 305 | 306 | } 307 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/AgentClassLoaderReference.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.ConcurrentHashMap; 5 | 6 | // @ThreadSafe 7 | public final class AgentClassLoaderReference { 8 | 9 | public static final int FIRST_PRECOMPILED_UUID = 1; 10 | public static final int MAX_PRECOMPILED_UUID = 25; 11 | private static int nextPrecompiledUuid = FIRST_PRECOMPILED_UUID; 12 | 13 | private static final Map UUID_AGENTCLASSLOADER = new ConcurrentHashMap<>(); 14 | 15 | private AgentClassLoaderReference() {} 16 | 17 | public static synchronized String nextPrecompiledUuid() { 18 | if (nextPrecompiledUuid > MAX_PRECOMPILED_UUID) { 19 | return null; 20 | } 21 | final String uuid = String.valueOf(nextPrecompiledUuid); 22 | nextPrecompiledUuid++; 23 | return uuid; 24 | } 25 | 26 | public static ClassLoader getAgentClassLoader(final String uuid) { 27 | if (uuid == null) { 28 | //fallback to context without using DynamicInstrumentationReflections 29 | return Thread.currentThread().getContextClassLoader(); 30 | } 31 | final ClassLoader classLoader = UUID_AGENTCLASSLOADER.get(uuid); 32 | if (classLoader == null) { 33 | //fallback to context without using DynamicInstrumentationReflections 34 | return Thread.currentThread().getContextClassLoader(); 35 | } 36 | //remove the reference as soon as possible so we don't create long holding security problems 37 | UUID_AGENTCLASSLOADER.remove(uuid); 38 | return classLoader; 39 | } 40 | 41 | public static boolean containsAgentClassLoader(final String uuid) { 42 | return UUID_AGENTCLASSLOADER.containsKey(uuid); 43 | } 44 | 45 | public static void setAgentClassLoader(final String uuid, final ClassLoader agentClassLoader) { 46 | UUID_AGENTCLASSLOADER.put(uuid, agentClassLoader); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/AgentInstrumentationInitializer.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | 5 | import javax.annotation.concurrent.NotThreadSafe; 6 | 7 | import org.springframework.instrument.InstrumentationSavingAgent; 8 | import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver; 9 | 10 | @NotThreadSafe 11 | public final class AgentInstrumentationInitializer { 12 | 13 | private AgentInstrumentationInitializer() { 14 | } 15 | 16 | public static void initialize(final String args, final Instrumentation inst) { 17 | if (InstrumentationLoadTimeWeaver.isInstrumentationAvailable()) { 18 | throw new IllegalStateException( 19 | "Instrumentation is already available, the agent should have been loaded already!"); 20 | } 21 | 22 | InstrumentationSavingAgent.premain(args, inst); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DummyAttachProvider.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | 6 | import com.sun.tools.attach.AttachNotSupportedException; 7 | import com.sun.tools.attach.VirtualMachine; 8 | import com.sun.tools.attach.VirtualMachineDescriptor; 9 | 10 | // @Immutable 11 | public class DummyAttachProvider extends com.sun.tools.attach.spi.AttachProvider { 12 | 13 | @Override 14 | public VirtualMachine attachVirtualMachine(final String arg0) throws AttachNotSupportedException, IOException { 15 | return null; 16 | } 17 | 18 | @Override 19 | public List listVirtualMachines() { 20 | return null; 21 | } 22 | 23 | @Override 24 | public String name() { 25 | return null; 26 | } 27 | 28 | @Override 29 | public String type() { 30 | return null; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // @Immutable 7 | public final class DynamicInstrumentationAgent { 8 | 9 | public static final String DEFAULT_UUID = "DEFAULT"; 10 | 11 | private DynamicInstrumentationAgent() {} 12 | 13 | public static void premain(final String args, final Instrumentation inst) throws Exception { 14 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 15 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 16 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 17 | .loadClass(agentClassLoaderReferenceClass.getName()); 18 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 19 | .getDeclaredMethod("getAgentClassLoader", String.class); 20 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, DEFAULT_UUID); 21 | if (agentClassLoader == null) { 22 | //fallback to contextClassLoader, don't use external dependencies 23 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 24 | } 25 | if (agentClassLoader == null) { 26 | agentClassLoader = systemClassLoader; 27 | } 28 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 29 | DynamicInstrumentationAgent.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 30 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 31 | Instrumentation.class); 32 | initializeMethod.invoke(null, args, inst); 33 | } 34 | 35 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 36 | premain(args, inst); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent.java.template: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_ { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = ""; 12 | 13 | private DynamicInstrumentationAgent_() { 14 | } 15 | 16 | public static void premain(final String args, final Instrumentation inst) throws Exception { 17 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 18 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 19 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 20 | .loadClass(agentClassLoaderReferenceClass.getName()); 21 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 22 | .getDeclaredMethod("getAgentClassLoader", String.class); 23 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 24 | if (agentClassLoader == null) { 25 | //fallback to contextClassLoader, don't use external dependencies 26 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 27 | } 28 | if (agentClassLoader == null) { 29 | agentClassLoader = systemClassLoader; 30 | } 31 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 32 | DynamicInstrumentationAgent_.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 33 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 34 | Instrumentation.class); 35 | initializeMethod.invoke(null, args, inst); 36 | } 37 | 38 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 39 | premain(args, inst); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgentCompiler.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.InputStreamReader; 7 | import java.util.List; 8 | import java.util.UUID; 9 | 10 | import de.invesdwin.instrument.internal.compile.DynamicInstrumentationClassInfo; 11 | import de.invesdwin.instrument.internal.compile.DynamicInstrumentationCompiler; 12 | 13 | // @Immutable 14 | public final class DynamicInstrumentationAgentCompiler { 15 | 16 | public static final String UUID_PLACEHOLDER = ""; 17 | public static final String TEMPLATE = DynamicInstrumentationAgent.class.getSimpleName() + ".java.template"; 18 | 19 | private DynamicInstrumentationAgentCompiler() {} 20 | 21 | public static DynamicInstrumentationClassInfo precompiled(final String uuid) { 22 | final String className = DynamicInstrumentationAgent.class.getSimpleName() + "_" + uuid; 23 | final String fqdn = DynamicInstrumentationAgent.class.getName() + "_" + uuid; 24 | final byte[] bytes = readPrecompiled(className); 25 | return new DynamicInstrumentationClassInfo(fqdn, bytes); 26 | } 27 | 28 | public static String nextCompileUuid() { 29 | return UUID.randomUUID().toString().replace("-", ""); 30 | } 31 | 32 | public static DynamicInstrumentationClassInfo compile(final String uuid) { 33 | final String template = readTemplate().replace(UUID_PLACEHOLDER, uuid); 34 | final List compiled; 35 | try { 36 | compiled = DynamicInstrumentationCompiler.compile(java.util.Arrays.asList(template)); 37 | } catch (final IOException e) { 38 | throw new RuntimeException("Error during compilation of: " + TEMPLATE, e); 39 | } 40 | if (compiled.size() != 1) { 41 | throw new RuntimeException( 42 | "Expecting exactly one but got [" + compiled.size() + "] compiled classes for: " + TEMPLATE); 43 | } 44 | return compiled.get(0); 45 | } 46 | 47 | private static String readTemplate() { 48 | try (InputStream resourceAsStream = DynamicInstrumentationAgentCompiler.class.getResourceAsStream(TEMPLATE)) { 49 | return readToString(resourceAsStream); 50 | } catch (final IOException e) { 51 | throw new RuntimeException("Error reading: " + TEMPLATE, e); 52 | } 53 | } 54 | 55 | private static String readToString(final InputStream in) throws IOException { 56 | final StringBuilder contentBuilder = new StringBuilder(); 57 | try (BufferedReader br = new BufferedReader(new InputStreamReader(in))) { 58 | String sCurrentLine; 59 | while ((sCurrentLine = br.readLine()) != null) { 60 | contentBuilder.append(sCurrentLine).append("\n"); 61 | } 62 | } 63 | return contentBuilder.toString(); 64 | } 65 | 66 | private static byte[] readPrecompiled(final String className) { 67 | try (InputStream resourceAsStream = DynamicInstrumentationAgentCompiler.class 68 | .getResourceAsStream(className + ".class")) { 69 | return readToBytes(resourceAsStream); 70 | } catch (final IOException e) { 71 | throw new RuntimeException("Error reading: " + className, e); 72 | } 73 | } 74 | 75 | private static byte[] readToBytes(final InputStream in) throws IOException { 76 | final java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream(); 77 | final byte[] buf = new byte[8192]; 78 | //convert file into array of bytes 79 | long count = 0; 80 | int n; 81 | while (-1 != (n = in.read(buf))) { 82 | out.write(buf, 0, n); 83 | count += n; 84 | } 85 | if (count == 0) { 86 | return null; 87 | } 88 | return out.toByteArray(); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_1.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_1 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "1"; 12 | 13 | private DynamicInstrumentationAgent_1() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_1.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | 35 | initializeMethod.invoke(null, args, inst); 36 | } 37 | 38 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 39 | premain(args, inst); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_10.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_10 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "10"; 12 | 13 | private DynamicInstrumentationAgent_10() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_10.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_11.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_11 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "11"; 12 | 13 | private DynamicInstrumentationAgent_11() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_11.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_12.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_12 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "12"; 12 | 13 | private DynamicInstrumentationAgent_12() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_12.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_13.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_13 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "13"; 12 | 13 | private DynamicInstrumentationAgent_13() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_13.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_14.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_14 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "14"; 12 | 13 | private DynamicInstrumentationAgent_14() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_14.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_15.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_15 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "15"; 12 | 13 | private DynamicInstrumentationAgent_15() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_15.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_16.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_16 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "16"; 12 | 13 | private DynamicInstrumentationAgent_16() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_16.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_17.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_17 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "17"; 12 | 13 | private DynamicInstrumentationAgent_17() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_17.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_18.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_18 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "18"; 12 | 13 | private DynamicInstrumentationAgent_18() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_18.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_19.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_19 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "19"; 12 | 13 | private DynamicInstrumentationAgent_19() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_19.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_2.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_2 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "2"; 12 | 13 | private DynamicInstrumentationAgent_2() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_2.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_20.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_20 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "20"; 12 | 13 | private DynamicInstrumentationAgent_20() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_20.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_21.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_21 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "21"; 12 | 13 | private DynamicInstrumentationAgent_21() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_21.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_22.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_22 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "22"; 12 | 13 | private DynamicInstrumentationAgent_22() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_22.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_23.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_23 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "23"; 12 | 13 | private DynamicInstrumentationAgent_23() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_23.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_24.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_24 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "24"; 12 | 13 | private DynamicInstrumentationAgent_24() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_24.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_25.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_25 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "25"; 12 | 13 | private DynamicInstrumentationAgent_25() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_25.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_3.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_3 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "3"; 12 | 13 | private DynamicInstrumentationAgent_3() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_3.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_4.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_4 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "4"; 12 | 13 | private DynamicInstrumentationAgent_4() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_4.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_5.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_5 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "5"; 12 | 13 | private DynamicInstrumentationAgent_5() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_5.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_6.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_6 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "6"; 12 | 13 | private DynamicInstrumentationAgent_6() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_6.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_7.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_7 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "7"; 12 | 13 | private DynamicInstrumentationAgent_7() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_7.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_8.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_8 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "8"; 12 | 13 | private DynamicInstrumentationAgent_8() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_8.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationAgent_9.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.Method; 5 | 6 | // CHECKSTYLE:OFF 7 | // @Immutable 8 | public final class DynamicInstrumentationAgent_9 { 9 | //CHECKSTYLE:ON 10 | 11 | private static final String UUID = "9"; 12 | 13 | private DynamicInstrumentationAgent_9() {} 14 | 15 | public static void premain(final String args, final Instrumentation inst) throws Exception { 16 | final Class agentClassLoaderReferenceClass = AgentClassLoaderReference.class; 17 | final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 18 | final Class systemAgentClassLoaderReferenceClass = systemClassLoader 19 | .loadClass(agentClassLoaderReferenceClass.getName()); 20 | final Method getAgentClassLoaderMethod = systemAgentClassLoaderReferenceClass 21 | .getDeclaredMethod("getAgentClassLoader", String.class); 22 | ClassLoader agentClassLoader = (ClassLoader) getAgentClassLoaderMethod.invoke(null, UUID); 23 | if (agentClassLoader == null) { 24 | //fallback to contextClassLoader, don't use external dependencies 25 | agentClassLoader = Thread.currentThread().getContextClassLoader(); 26 | } 27 | if (agentClassLoader == null) { 28 | agentClassLoader = systemClassLoader; 29 | } 30 | final Class agentInstrumentationInitializer = agentClassLoader.loadClass( 31 | DynamicInstrumentationAgent_9.class.getPackage().getName() + ".AgentInstrumentationInitializer"); 32 | final Method initializeMethod = agentInstrumentationInitializer.getDeclaredMethod("initialize", String.class, 33 | Instrumentation.class); 34 | initializeMethod.invoke(null, args, inst); 35 | } 36 | 37 | public static void agentmain(final String args, final Instrumentation inst) throws Exception { 38 | premain(args, inst); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/DynamicInstrumentationLoadAgentMain.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.io.File; 4 | import java.lang.reflect.Constructor; 5 | import java.lang.reflect.InvocationTargetException; 6 | import java.util.List; 7 | 8 | // @Immutable 9 | public final class DynamicInstrumentationLoadAgentMain { 10 | 11 | private DynamicInstrumentationLoadAgentMain() {} 12 | 13 | public static void main(final String[] args) { 14 | if (args.length != 2) { 15 | throw new IllegalArgumentException("Usage: " + DynamicInstrumentationLoadAgentMain.class.getSimpleName() 16 | + " "); 17 | } 18 | final String pid = args[0]; 19 | final String agentJarAbsolutePath = args[1]; 20 | loadAgent(pid, agentJarAbsolutePath); 21 | } 22 | 23 | /** 24 | * https://github.com/jmockit/jmockit1/blob/8ea057ffe08a3ef9788ee383db695a3a404d3c86/main/src/mockit/internal/startup/AgentLoader.java 25 | * 26 | * http://tuhrig.de/implementing-interfaces-and-abstract-classes-on-the-fly/ 27 | */ 28 | public static void loadAgent(final String pid, final String agentJarAbsolutePath) { 29 | //use reflection since tools.jar has been added to the classpath dynamically 30 | try { 31 | final Class attachProviderClass = Class.forName("com.sun.tools.attach.spi.AttachProvider"); 32 | final List providers = (List) attachProviderClass.getMethod("providers").invoke(null); 33 | final Class virtualMachineClass; 34 | final Object virtualMachine; 35 | if (providers.isEmpty()) { 36 | final String virtualMachineClassName = findVirtualMachineClassNameAccordingToOS(); 37 | virtualMachineClass = Class.forName(virtualMachineClassName); 38 | final Constructor vmConstructor = virtualMachineClass.getDeclaredConstructor(attachProviderClass, 39 | String.class); 40 | vmConstructor.setAccessible(true); 41 | final Object dummyAttachProvider = Class.forName("de.invesdwin.instrument.internal.DummyAttachProvider") 42 | .getDeclaredConstructor() 43 | .newInstance(); 44 | virtualMachine = vmConstructor.newInstance(dummyAttachProvider, pid); 45 | } else { 46 | virtualMachineClass = Class.forName("com.sun.tools.attach.VirtualMachine"); 47 | virtualMachine = virtualMachineClass.getMethod("attach", String.class).invoke(null, pid); 48 | } 49 | virtualMachineClass.getMethod("loadAgent", String.class).invoke(virtualMachine, agentJarAbsolutePath); 50 | virtualMachineClass.getMethod("detach").invoke(virtualMachine); 51 | } catch (final IllegalAccessException e) { 52 | throw new RuntimeException(e); 53 | } catch (final IllegalArgumentException e) { 54 | throw new RuntimeException(e); 55 | } catch (final InvocationTargetException e) { 56 | throw new RuntimeException(e); 57 | } catch (final NoSuchMethodException e) { 58 | throw new RuntimeException(e); 59 | } catch (final SecurityException e) { 60 | throw new RuntimeException(e); 61 | } catch (final ClassNotFoundException e) { 62 | throw new RuntimeException(newHelpMessageForNonHotSpotVM(), e); 63 | } catch (final InstantiationException e) { 64 | throw new RuntimeException(e); 65 | } catch (final NoClassDefFoundError e) { 66 | throw new IllegalStateException("Native library for Attach API not available in this JRE", e); 67 | } catch (final UnsatisfiedLinkError e) { 68 | throw new IllegalStateException("Native library for Attach API not available in this JRE", e); 69 | } 70 | } 71 | 72 | private static String findVirtualMachineClassNameAccordingToOS() { 73 | if (File.separatorChar == '\\') { 74 | return "sun.tools.attach.WindowsVirtualMachine"; 75 | } 76 | 77 | //CHECKSTYLE:OFF 78 | final String osName = System.getProperty("os.name"); 79 | //CHECKSTYLE:ON 80 | 81 | if (osName.startsWith("Linux") || osName.startsWith("LINUX")) { 82 | return "sun.tools.attach.LinuxVirtualMachine"; 83 | } 84 | 85 | if (osName.contains("FreeBSD") || osName.startsWith("Mac OS X")) { 86 | return "sun.tools.attach.BsdVirtualMachine"; 87 | } 88 | 89 | if (osName.startsWith("Solaris") || osName.contains("SunOS")) { 90 | return "sun.tools.attach.SolarisVirtualMachine"; 91 | } 92 | 93 | if (osName.contains("AIX")) { 94 | return "sun.tools.attach.AixVirtualMachine"; 95 | } 96 | 97 | throw new IllegalStateException("Cannot use Attach API on unknown OS: " + osName); 98 | } 99 | 100 | private static String newHelpMessageForNonHotSpotVM() { 101 | //CHECKSTYLE:OFF 102 | final String vmName = System.getProperty("java.vm.name"); 103 | //CHECKSTYLE:ON 104 | String helpMessage = "To run on " + vmName; 105 | 106 | if (vmName.contains("J9")) { 107 | helpMessage += ", add /lib/tools.jar to the runtime classpath (before invesdwin-instrument), or"; 108 | } 109 | 110 | return helpMessage + " use -javaagent:invesdwin-instrument.jar"; 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/JdkFilesFinder.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.io.File; 4 | import java.util.ArrayList; 5 | import java.util.Comparator; 6 | import java.util.LinkedHashSet; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | import javax.annotation.concurrent.NotThreadSafe; 11 | 12 | @NotThreadSafe 13 | public class JdkFilesFinder { 14 | 15 | private final Set potentialFolders; 16 | 17 | public JdkFilesFinder() { 18 | //determine the java home via the system variables 19 | final Set javaHomes = new LinkedHashSet(); 20 | //CHECKSTYLE:OFF 21 | for (final String javaHomeStr : new String[] { System.getenv("JAVA_HOME"), System.getProperty("java.home") }) { 22 | //CHECKSTYLE:ON 23 | if (!org.springframework.util.StringUtils.isEmpty(javaHomeStr)) { 24 | final File javaHome = new File(javaHomeStr); 25 | if (javaHome.exists()) { 26 | javaHomes.add(javaHome); 27 | } 28 | } 29 | } 30 | //add parent directories on windows to get the jdk from the jre folder 31 | final List potentialOtherJavaHomes = new ArrayList(); 32 | for (final File javaHome : new ArrayList(javaHomes)) { 33 | if (javaHome.getAbsolutePath().contains("jre")) { 34 | for (final File dir : javaHome.getParentFile().listFiles()) { 35 | potentialOtherJavaHomes.add(dir); 36 | } 37 | } 38 | } 39 | //sort file names descending to have the highest jdk version be searched first 40 | java.util.Collections.sort(potentialOtherJavaHomes, new Comparator() { 41 | @Override 42 | public int compare(final File o1, final File o2) { 43 | return o1.getName().compareTo(o2.getName()) * -1; 44 | } 45 | }); 46 | javaHomes.addAll(potentialOtherJavaHomes); 47 | //search for special subfolders that might contain the desired files 48 | this.potentialFolders = new LinkedHashSet(); 49 | for (final File javaHome : javaHomes) { 50 | if (!org.springframework.util.StringUtils.isEmpty(javaHome)) { 51 | for (final String folderName : new String[] { "bin", "lib" }) { 52 | addPotentialFolderIfExists(new File(javaHome, folderName)); 53 | addPotentialFolderIfExists(new File(javaHome, "../" + folderName)); 54 | addPotentialFolderIfExists(new File(javaHome, "jre/" + folderName)); 55 | addPotentialFolderIfExists(new File(javaHome, "../jre/" + folderName)); 56 | } 57 | } 58 | } 59 | } 60 | 61 | private void addPotentialFolderIfExists(final File e) { 62 | if (e.exists()) { 63 | potentialFolders.add(e); 64 | } 65 | } 66 | 67 | public File findToolsJar() { 68 | File toolsJar = null; 69 | final String potentialFileName = "tools.jar"; 70 | for (final File dir : potentialFolders) { 71 | toolsJar = findFileRecursive(dir, potentialFileName); 72 | if (toolsJar != null) { 73 | break; 74 | } 75 | } 76 | assertFileFound(toolsJar, potentialFileName); 77 | return toolsJar; 78 | } 79 | 80 | private void assertFileFound(final File toolsJar, final Object potentialFileNames) { 81 | if (!toolsJar.exists()) { 82 | throw new IllegalStateException("No " + potentialFileNames + " found in " + potentialFolders 83 | + ". Please make sure a JDK is installed and JAVA_HOME points there."); 84 | } 85 | } 86 | 87 | public File findAttachLib() { 88 | File attachLib = null; 89 | final List potentialFileNames = java.util.Arrays.asList("attach.dll", "libattach.so", 90 | "libattach.dylib"); 91 | OUTER: for (final File dir : potentialFolders) { 92 | for (final String attachLibFileName : potentialFileNames) { 93 | attachLib = findFileRecursive(dir, attachLibFileName); 94 | if (attachLib != null) { 95 | break OUTER; 96 | } 97 | } 98 | } 99 | assertFileFound(attachLib, potentialFileNames); 100 | return attachLib; 101 | } 102 | 103 | private File findFileRecursive(final File rootDir, final String fileName) { 104 | if (!rootDir.exists()) { 105 | return null; 106 | } 107 | final File[] files = rootDir.listFiles(); 108 | final List directories = new ArrayList(files.length); 109 | for (final File file : files) { 110 | if (file.getName().equals(fileName)) { 111 | return file; 112 | } else if (file.isDirectory()) { 113 | directories.add(file); 114 | } 115 | } 116 | 117 | for (final File directory : directories) { 118 | final File file = findFileRecursive(directory, fileName); 119 | if (file != null) { 120 | return file; 121 | } 122 | } 123 | 124 | return null; 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/RemoveFinalModifierJava9.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal; 2 | 3 | import java.lang.invoke.MethodHandles; 4 | import java.lang.reflect.Field; 5 | import java.lang.reflect.Method; 6 | import java.lang.reflect.Modifier; 7 | 8 | import javax.annotation.concurrent.Immutable; 9 | 10 | @Immutable 11 | public final class RemoveFinalModifierJava9 { 12 | 13 | private RemoveFinalModifierJava9() {} 14 | 15 | public static void removeFinalModifierJava9(final Field field) throws Exception { 16 | final Method privateLookupInMethod = MethodHandles.class.getDeclaredMethod("privateLookupIn", Class.class, 17 | MethodHandles.Lookup.class); 18 | final MethodHandles.Lookup lookup = (MethodHandles.Lookup) privateLookupInMethod.invoke(null, Field.class, 19 | MethodHandles.lookup()); 20 | final Method findVarHandleMethod = MethodHandles.Lookup.class.getDeclaredMethod("findVarHandle", Class.class, 21 | String.class, Class.class); 22 | final java.lang.invoke.VarHandle varHandle = (java.lang.invoke.VarHandle) findVarHandleMethod.invoke(lookup, 23 | Field.class, "modifiers", int.class); 24 | varHandle.set(field, field.getModifiers() & ~Modifier.FINAL); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/compile/DynamicInstrumentationClassInfo.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal.compile; 2 | 3 | import java.io.InputStream; 4 | 5 | // @NotThreadSafe 6 | public class DynamicInstrumentationClassInfo { 7 | /** 8 | * fully qualified classname in a format suitable for Class.forName 9 | */ 10 | private final String className; 11 | 12 | /** 13 | * bytecode for the class 14 | */ 15 | private final byte[] bytes; 16 | 17 | public DynamicInstrumentationClassInfo(final String aClassName, final byte[] aBytes) { 18 | className = aClassName.replace('/', '.'); 19 | // className = aClassName.replace('.', '/'); 20 | bytes = aBytes; 21 | } 22 | 23 | public String getSimpleName() { 24 | return className.substring(className.lastIndexOf(".") + 1); 25 | } 26 | 27 | public byte[] getBytes() { 28 | return bytes; 29 | } 30 | 31 | public InputStream newInputStream() { 32 | return new java.io.ByteArrayInputStream(bytes); 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return className; 38 | } 39 | 40 | @Override 41 | public int hashCode() { 42 | return className.hashCode(); 43 | } 44 | 45 | @Override 46 | public boolean equals(final Object obj) { 47 | if (this == obj) { 48 | return true; 49 | } 50 | if ((obj instanceof DynamicInstrumentationClassInfo) 51 | && ((DynamicInstrumentationClassInfo) obj).className.equals(this.className)) { 52 | return true; 53 | } 54 | return false; 55 | } 56 | } -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/main/java/de/invesdwin/instrument/internal/compile/DynamicInstrumentationCompiler.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal.compile; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.regex.Matcher; 10 | import java.util.regex.Pattern; 11 | 12 | import javax.tools.JavaCompiler; 13 | import javax.tools.ToolProvider; 14 | 15 | import de.invesdwin.instrument.DynamicInstrumentationProperties; 16 | 17 | /** 18 | * Extracted from: https://github.com/kilim/kilim/blob/master/src/kilim/tools/Javac.java 19 | * 20 | * @author subes 21 | * 22 | */ 23 | //CHECKSTYLE:OFF 24 | //@NotThreadSafe 25 | public final class DynamicInstrumentationCompiler { 26 | 27 | private DynamicInstrumentationCompiler() {} 28 | 29 | /** 30 | * Given a list of file-scope java code (equivalent to a .java file, including package and import declarations), 31 | * compile() invokes javac to compile them, produce classfiles and return a list of pairs. 32 | * 33 | * compile() dumps the source strings into their respective files, has javac compile them, then reads back the 34 | * equivalent class files. The name of the source file is gleaned from the string itself; a string containing 35 | * "public class Foo" is stored in tmpDir/Foo.java (where tmpDir is a temporary directory that's deleted after the 36 | * compilation), and if no public class or interface is found, the name of the first class in the string is used. 37 | * 38 | * Note that the list of returned classes may be larger than list of sources 39 | * 40 | * Note: the java compiler api is ill-defined and this class should not be considered production. specifically, the 41 | * classpath appears to depend on the execution environment, eg command line maven vs IDE vs the java command line 42 | * 43 | * @param srcCodes 44 | * . List of strings. 45 | * @return List. className is fully qualified, and byte[] contains the bytecode of the class. 46 | * @throws IOException 47 | */ 48 | public static List compile(final List srcCodes) throws IOException { 49 | 50 | final List srcInfos = getSourceInfos(srcCodes); 51 | 52 | final File rootDir = getTmpDir(); // something like "/tmp/kilim$2348983948" 53 | 54 | final File classDir = new File(rootDir.getAbsolutePath() + File.separatorChar + "classes"); 55 | classDir.mkdir(); // "/classes" 56 | 57 | /** 58 | * the compiler classpath appears to depend on the class.path system variable which changes depending on the 59 | * execution environment, eg command line maven vs command line java vs IDE vs ant to limit this dependence, 60 | * generate a classpath from the class loader urls instead 61 | */ 62 | final String cp = getClassPath(null, null).join(); 63 | 64 | final ArrayList args = new ArrayList(); 65 | add(args, "-d", classDir.getAbsolutePath()); 66 | if (!cp.isEmpty()) { 67 | add(args, "-cp", cp); 68 | } 69 | for (final SourceInfo srci : srcInfos) { 70 | final String name = rootDir.getAbsolutePath() + File.separatorChar + srci.className + ".java"; 71 | writeFile(new File(name), srci.srcCode.getBytes()); 72 | args.add(name); 73 | } 74 | final String[] arguments = args.toArray(new String[0]); 75 | 76 | final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 77 | compiler.run(null, null, null, arguments); 78 | 79 | final List ret = new ArrayList(); 80 | addClasses(ret, "", classDir); 81 | deleteDir(rootDir); 82 | return ret; 83 | } 84 | 85 | static void add(final ArrayList list, final String... vals) { 86 | for (final String val : vals) { 87 | list.add(val); 88 | } 89 | } 90 | 91 | /** 92 | * get the class path comprising the paths of URL class loaders ancestors 93 | * 94 | * @param start 95 | * start with the class loader that loaded this object, or null for this method's class 96 | * @param end 97 | * the last classloader to consider, or null to include everything up to but not including the system 98 | * class loader 99 | * @return the URLs 100 | */ 101 | public static ClassPath getClassPath(final Class start, final ClassLoader end) { 102 | final ClassPath result = new ClassPath(); 103 | final ClassLoader sys = end == null ? ClassLoader.getSystemClassLoader() : end.getParent(); 104 | ClassLoader cl = (start == null ? DynamicInstrumentationCompiler.class : start).getClassLoader(); 105 | // FIXME::rhetorical - what order should the classpath be ? 106 | // the reality is that calling the compiler cannot be 100% robust 107 | // so this detail is likely insignificant 108 | for (; cl != null & cl != sys; cl = cl.getParent()) { 109 | if (cl instanceof java.net.URLClassLoader) { 110 | for (final java.net.URL url : ((java.net.URLClassLoader) cl).getURLs()) { 111 | result.add(url.getPath()); 112 | } 113 | } 114 | } 115 | return result; 116 | } 117 | 118 | /** a collection of class path elements */ 119 | public static class ClassPath extends ArrayList { 120 | /** get the command-line-style classpath string */ 121 | public String join() { 122 | String cp = ""; 123 | for (final String url : this) { 124 | cp += (cp.isEmpty() ? "" : File.pathSeparator) + url; 125 | } 126 | return cp; 127 | } 128 | } 129 | 130 | private static List getSourceInfos(final List srcCodes) { 131 | final List srcInfos = new ArrayList(srcCodes.size()); 132 | for (final String srcCode : srcCodes) { 133 | srcInfos.add(getSourceInfo(srcCode)); 134 | } 135 | return srcInfos; 136 | } 137 | 138 | private static final Pattern publicClassNameRegexp = Pattern.compile("public +(?:class|interface) +(\\w+)"); 139 | private static final Pattern classNameRegexp = Pattern.compile("(?:class|interface) +(\\w+)"); 140 | 141 | private static SourceInfo getSourceInfo(final String srcCode) { 142 | Matcher m = publicClassNameRegexp.matcher(srcCode); 143 | if (m.find()) { 144 | return new SourceInfo(m.group(1), srcCode); 145 | } else { 146 | m = classNameRegexp.matcher(srcCode); 147 | if (m.find()) { 148 | return new SourceInfo(m.group(1), srcCode); 149 | } else { 150 | throw new IllegalArgumentException( 151 | "No class or interface definition found in src: \n'" + srcCode + "'"); 152 | } 153 | } 154 | } 155 | 156 | private static File getTmpDir() throws IOException { 157 | final String name = DynamicInstrumentationProperties.PROCESS_TEMP_DIRECTORY + "/" 158 | + DynamicInstrumentationCompiler.class.getSimpleName(); 159 | final File rootDir = new File(name); 160 | if (!rootDir.mkdir()) { 161 | throw new IOException("Unable to make tmp directory " + rootDir.getAbsolutePath()); 162 | } 163 | return rootDir; 164 | } 165 | 166 | private static void deleteDir(final File rootDir) { 167 | for (final File f : rootDir.listFiles()) { 168 | if (f.isDirectory()) { 169 | deleteDir(f); 170 | } else { 171 | if (!f.delete()) { 172 | System.err.println("Unable to delete " + f.getAbsolutePath()); 173 | } 174 | } 175 | } 176 | if (!rootDir.delete()) { 177 | System.err.println("Unable to delete " + rootDir.getAbsolutePath()); 178 | } 179 | } 180 | 181 | private static void addClasses(final List ret, final String pkgName, 182 | final File dir) throws IOException { 183 | for (final File f : dir.listFiles()) { 184 | final String fname = f.getName(); 185 | if (f.isDirectory()) { 186 | final String qname = pkgName + fname + "."; 187 | addClasses(ret, qname, f); 188 | } else if (fname.endsWith(".class")) { 189 | final String qname = pkgName + fname.substring(0, fname.length() - 6); 190 | ret.add(new DynamicInstrumentationClassInfo(qname, readFile(f))); 191 | } else { 192 | System.err.println("Unexpected file : " + f.getAbsolutePath()); 193 | } 194 | } 195 | } 196 | 197 | private static byte[] readFile(final File f) throws IOException { 198 | int len = (int) f.length(); 199 | final byte[] buf = new byte[len]; 200 | final FileInputStream fis = new FileInputStream(f); 201 | int off = 0; 202 | while (len > 0) { 203 | final int n = fis.read(buf, off, len); 204 | if (n == -1) { 205 | throw new IOException("Unexpected EOF reading " + f.getAbsolutePath()); 206 | } 207 | off += n; 208 | len -= n; 209 | } 210 | return buf; 211 | } 212 | 213 | private static void writeFile(final File f, final byte[] srcCode) throws IOException { 214 | final FileOutputStream fos = new FileOutputStream(f); 215 | fos.write(srcCode); 216 | fos.close(); 217 | } 218 | 219 | private static class SourceInfo { 220 | public SourceInfo(final String nm, final String code) { 221 | className = nm; 222 | srcCode = code; 223 | } 224 | 225 | public String className; 226 | public String srcCode; 227 | } 228 | } -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/test/java/burningwave.static.properties: -------------------------------------------------------------------------------- 1 | banner.hide=true 2 | managed-logger.repository.enabled=false 3 | #avoiding the automatic call on startup of Burningwave Core to method 4 | #org.burningwave.core.assembler.StaticComponentContainer.Modules.exportAllToAll() 5 | #which exports all modules to all modules 6 | modules.export-all-to-all=false 7 | #prevent threads from spawning unnecessarily: https://github.com/burningwave/core/issues/10 8 | background-executor.all-tasks-monitoring.enabled=false 9 | static-component-container.on-close.close-all-component-containers=false 10 | static-component-container.on-close.close-file-system-helper=false -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/test/java/de/invesdwin/instrument/DynamicInstrumentationLoaderTest.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument; 2 | 3 | import javax.annotation.concurrent.NotThreadSafe; 4 | 5 | import org.burningwave.core.assembler.StaticComponentContainer; 6 | import org.junit.jupiter.api.Test; 7 | 8 | @NotThreadSafe 9 | public class DynamicInstrumentationLoaderTest { 10 | 11 | @Test 12 | public void test() { 13 | StaticComponentContainer.Modules.exportAllToAll(); 14 | DynamicInstrumentationLoader.waitForInitialized(); 15 | DynamicInstrumentationLoader.initLoadTimeWeavingContext(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/invesdwin-instrument/src/test/java/de/invesdwin/instrument/internal/compile/DynamicInstrumentationAgentGenerator.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.instrument.internal.compile; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.nio.charset.Charset; 6 | 7 | import javax.annotation.concurrent.NotThreadSafe; 8 | 9 | import org.junit.jupiter.api.Test; 10 | 11 | import de.invesdwin.instrument.internal.AgentClassLoaderReference; 12 | import de.invesdwin.instrument.internal.DynamicInstrumentationAgent; 13 | import de.invesdwin.instrument.internal.DynamicInstrumentationAgentCompiler; 14 | 15 | @NotThreadSafe 16 | public class DynamicInstrumentationAgentGenerator { 17 | 18 | @Test 19 | public void test() throws IOException { 20 | final File folder = new File( 21 | "src/main/java/" + DynamicInstrumentationAgent.class.getPackage().getName().replace(".", "/")); 22 | final String template = org.apache.commons.io.FileUtils.readFileToString( 23 | new File(folder, DynamicInstrumentationAgentCompiler.TEMPLATE), Charset.defaultCharset()); 24 | for (int i = AgentClassLoaderReference.FIRST_PRECOMPILED_UUID; i <= AgentClassLoaderReference.MAX_PRECOMPILED_UUID; i++) { 25 | final File newFile = new File(folder, 26 | DynamicInstrumentationAgent.class.getSimpleName() + "_" + i + ".java"); 27 | org.apache.commons.io.FileUtils.writeStringToFile(newFile, 28 | template.replace(DynamicInstrumentationAgentCompiler.UUID_PLACEHOLDER, "" + i), 29 | Charset.defaultCharset()); 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /invesdwin-instrument-parent/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | de.invesdwin 5 | invesdwin-bom 6 | 1.0.18-SNAPSHOT 7 | 8 | 9 | invesdwin-instrument-parent 10 | 1.0.15-SNAPSHOT 11 | pom 12 | 13 | 14 | 15 | GNU Lesser General Public License (LGPL), Version 3.0 16 | http://www.gnu.org/licenses/lgpl-3.0.html 17 | 18 | 19 | 20 | 21 | invesdwin-instrument 22 | invesdwin-instrument-burningwave 23 | 24 | 25 | 26 | UTF-8 27 | UTF-8 28 | 1.8 29 | 30 | 3.2.1 31 | 5.0 32 | 1.0.14-SNAPSHOT 33 | 3.3.0 34 | 0.1 35 | 36 | 37 | 38 | 39 | 40 | de.invesdwin 41 | invesdwin-maven-plugin 42 | ${project.version.invesdwin-maven-plugin} 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | ${basedir}/src/main/resources 51 | 52 | 53 | false 54 | ${basedir}/src/main/java 55 | 56 | **/* 57 | 58 | 59 | **/*.java 60 | 61 | 62 | 63 | 64 | 65 | ${basedir}/src/test/resources 66 | 67 | 68 | false 69 | ${basedir}/src/test/java 70 | 71 | **/* 72 | 73 | 74 | **/*.java 75 | 76 | 77 | 78 | 79 | 80 | org.bsc.maven 81 | maven-processor-plugin 82 | ${version.maven-processor-plugin} 83 | 84 | 85 | process 86 | 87 | process 88 | 89 | generate-sources 90 | 91 | ${project.build.directory}/generated-sources/apt 92 | false 93 | 94 | 95 | 96 | process-test 97 | 98 | process-test 99 | 100 | generate-test-sources 101 | 102 | ${project.build.directory}/generated-test-sources/apt 103 | false 104 | 105 | 106 | 107 | 108 | 109 | org.apache.maven.plugins 110 | maven-source-plugin 111 | ${version.maven-source-plugin} 112 | 113 | 114 | attach-sources 115 | 116 | jar 117 | 118 | 119 | 120 | 121 | 122 | de.invesdwin 123 | invesdwin-maven-plugin 124 | ${project.version.invesdwin-maven-plugin} 125 | 126 | 127 | 128 | initialize 129 | generate-sources 130 | compile 131 | 132 | 133 | true 134 | ${version.compiler} 135 | 136 | 137 | 138 | 139 | 140 | org.apache.maven.plugins 141 | maven-jar-plugin 142 | ${version.maven-jar-plugin} 143 | 144 | 145 | 146 | 147 | 148 | 149 | invesdwin-oss 150 | invesdwin-oss 151 | https://invesdwin.de/repo/invesdwin-oss 152 | 153 | 154 | invesdwin-oss 155 | invesdwin-oss 156 | https://invesdwin.de/repo/invesdwin-oss 157 | 158 | 159 | 160 | 161 | 162 | invesdwin-oss 163 | https://invesdwin.de/repo/invesdwin-oss-remote 164 | 165 | 166 | 167 | 168 | invesdwin-oss 169 | https://invesdwin.de/repo/invesdwin-oss-remote 170 | 171 | 172 | 173 | 174 | https://github.com/invesdwin/invesdwin-instrument 175 | scm:git:https://github.com/invesdwin/invesdwin-instrument.git 176 | HEAD 177 | 178 | 179 | 180 | jenkins 181 | https://invesdwin.de/jenkins/job/dgr-deploy-invesdwin-instrument/ 182 | 183 | 184 | 185 | 186 | jacoco 187 | 188 | false 189 | 190 | 191 | 192 | 193 | org.jacoco 194 | jacoco-maven-plugin 195 | 196 | true 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/.gitignore: -------------------------------------------------------------------------------- 1 | /.gradle/ 2 | /build/ 3 | /.settings/ 4 | /bin/ 5 | /.classpath 6 | /.project 7 | /.apt_generated/ 8 | /.apt_generated_tests/ 9 | /.factorypath 10 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | // Plugins DSL: 3 | id 'java' 4 | id 'eclipse' 5 | id 'org.springframework.boot' version '2.3.12.RELEASE' 6 | id 'io.spring.dependency-management' version '1.0.11.RELEASE' 7 | id 'io.franzbecker.gradle-lombok' version '4.0.0' 8 | id 'com.diffplug.eclipse.apt' version '3.31.0' 9 | } 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | sourceCompatibility = 1.8 16 | targetCompatibility = 1.8 17 | configurations.compileOnly.setCanBeResolved(true) 18 | eclipse.project { 19 | natures 'org.eclipse.buildship.core.gradleprojectnature' 20 | } 21 | 22 | ext { 23 | springSecurityOauth2Version = '2.3.8.RELEASE' 24 | postgresqlCPVersion = '42.2.23' 25 | hikariCPVersion = '4.0.3' 26 | mapstructVersion = '1.4.2.Final' 27 | quartzVersion = '2.3.2' 28 | commonsioVersion = '2.11.0' 29 | swaggerVersion = '3.0.0' 30 | aspectjWeaverVersion = '1.9.7' 31 | ztExecVersion = '1.12' 32 | } 33 | 34 | dependencies { 35 | 36 | // embedded container 37 | //compileOnly 'org.springframework.boot:spring-boot-starter-web' 38 | implementation 'org.springframework.boot:spring-boot-starter-undertow' 39 | 40 | implementation 'org.springframework.boot:spring-boot-starter-validation' 41 | implementation 'org.springframework.boot:spring-boot-starter-websocket' 42 | implementation 'org.springframework:spring-messaging' 43 | 44 | // Spring data 45 | //implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 46 | implementation 'org.springframework:spring-tx' 47 | 48 | // security 49 | //implementation 'org.springframework.boot:spring-boot-starter-security' 50 | //implementation "org.springframework.security.oauth:spring-security-oauth2:$springSecurityOauth2Version" 51 | 52 | // postgres 53 | implementation "org.postgresql:postgresql:$postgresqlCPVersion" 54 | 55 | // HikariCP 56 | implementation "com.zaxxer:HikariCP:$hikariCPVersion" 57 | 58 | // Java Bean mapper 59 | implementation "org.mapstruct:mapstruct:$mapstructVersion" 60 | 61 | // cache 62 | implementation 'org.springframework.boot:spring-boot-starter-cache' 63 | implementation 'org.ehcache:ehcache' 64 | 65 | 66 | // quartz 67 | implementation 'org.springframework:spring-context-support' 68 | implementation "org.quartz-scheduler:quartz:$quartzVersion" 69 | 70 | // apche library 71 | implementation "commons-io:commons-io:$commonsioVersion" 72 | implementation 'org.apache.commons:commons-lang3' 73 | implementation 'org.apache.httpcomponents:httpclient' 74 | 75 | // swagger 76 | implementation "io.springfox:springfox-boot-starter:$swaggerVersion" 77 | 78 | // @EnableLoadTimeWeaving 79 | implementation "org.aspectj:aspectjweaver:$aspectjWeaverVersion" 80 | implementation "org.zeroturnaround:zt-exec:$ztExecVersion" 81 | implementation 'org.springframework:spring-instrument' 82 | implementation 'org.springframework:spring-aspects' 83 | implementation 'org.springframework.boot:spring-boot-starter-aop' 84 | 85 | // local libs 86 | implementation fileTree(dir: 'libs', include: ['*.jar']) 87 | 88 | // Enable annotation processor 89 | annotationProcessor "org.projectlombok:lombok" 90 | annotationProcessor "org.springframework.boot:spring-boot-configuration-processor" 91 | annotationProcessor "org.mapstruct:mapstruct-processor:$mapstructVersion" 92 | //annotationProcessor "org.projectlombok:lombok-mapstruct-binding:0.2.0" 93 | 94 | implementation 'org.burningwave:core:10.0.0' 95 | developmentOnly 'org.springframework.boot:spring-boot-devtools' 96 | 97 | // Spring test 98 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 99 | testImplementation 'org.junit.platform:junit-platform-commons:1.7.2' 100 | } 101 | 102 | 103 | configurations { 104 | all { 105 | exclude module: 'spring-boot-starter-tomcat' 106 | exclude module: 'org.apache.tomcat.embed' 107 | 108 | // exclude older HikariCP 109 | exclude group: 'com.zaxxer', module: 'HikariCP-java6' 110 | 111 | // exclude other log implementation 112 | exclude group: 'commons-logging', module: 'commons-logging' 113 | exclude group: 'org.slf4j', module: 'slf4j-log4j12' 114 | exclude group: 'log4j', module: 'log4j' 115 | exclude group: 'org.apache.logging.log4j', module: 'log4j-api' 116 | exclude group: 'org.apache.logging.log4j', module: 'log4j-to-slf4j' 117 | exclude group: 'org.slf4j', module: 'jul-to-slf4j' 118 | exclude group: 'org.slf4j', module: 'jcl-over-slf4j' 119 | } 120 | } 121 | 122 | bootJar { 123 | mainClassName = 'com.sample.api.server.Application' 124 | } -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/invesdwin/invesdwin-instrument/b61c1c076c30957d182099848532c3db0907471e/tests/springboot-devtools-testapp/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/libs/invesdwin-instrument-1.0.14.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/invesdwin/invesdwin-instrument/b61c1c076c30957d182099848532c3db0907471e/tests/springboot-devtools-testapp/libs/invesdwin-instrument-1.0.14.jar -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * The settings file is used to specify which projects to include in your build. 5 | * 6 | * Detailed information about configuring a multi-project build in Gradle can be found 7 | * in the user manual at https://docs.gradle.org/6.8/userguide/multi_project_builds.html 8 | */ 9 | 10 | rootProject.name = 'springboot-devtools-testapp' 11 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/java/com/sample/api/server/Application.java: -------------------------------------------------------------------------------- 1 | package com.sample.api.server; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | import java.lang.reflect.InvocationTargetException; 5 | import java.lang.reflect.Method; 6 | 7 | import org.aspectj.weaver.loadtime.Agent; 8 | import org.burningwave.core.assembler.StaticComponentContainer; 9 | import org.springframework.boot.SpringApplication; 10 | import org.springframework.boot.autoconfigure.SpringBootApplication; 11 | import org.springframework.boot.builder.SpringApplicationBuilder; 12 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 13 | import org.springframework.instrument.InstrumentationSavingAgent; 14 | 15 | import com.sample.api.server.test.TestAspectUseCase; 16 | 17 | import de.invesdwin.instrument.DynamicInstrumentationLoader; 18 | 19 | @SpringBootApplication(scanBasePackages = "com.sample.api.server") 20 | public class Application extends SpringBootServletInitializer { 21 | 22 | @Override 23 | protected SpringApplicationBuilder configure(final SpringApplicationBuilder application) { 24 | return application.sources(Application.class); 25 | } 26 | 27 | public static void main(final String[] args) throws Throwable { 28 | load(); 29 | 30 | /* 31 | * Start (or restart inside devtools) the spring application 32 | */ 33 | SpringApplication.run(Application.class, args); 34 | } 35 | 36 | private static void load() 37 | throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { 38 | if (StaticComponentContainer.Modules != null) { 39 | // Java 16 workaround for add-opens 40 | StaticComponentContainer.Modules.exportAllToAll(); 41 | } 42 | 43 | // dynamically attach java agent to jvm if not already present 44 | DynamicInstrumentationLoader.waitForInitialized(); 45 | 46 | // weave all classes before they are loaded as beans 47 | DynamicInstrumentationLoader.initLoadTimeWeavingContext(); 48 | 49 | /* 50 | * make sure aspectj-LTW is loaded also into 51 | * org.springframework.boot.devtools.restart.RestartLauncher classloader 52 | */ 53 | org.aspectj.weaver.loadtime.Agent.agentmain("", InstrumentationSavingAgent.getInstrumentation()); 54 | // test that the aspect works fine 55 | new TestAspectUseCase().testAspect(); 56 | 57 | /* 58 | * try to load lombok 59 | */ 60 | final Class lombokAgentClass = Class.forName("lombok.launch.Agent"); 61 | final Method agentMainMethod = lombokAgentClass.getDeclaredMethod("agentmain", String.class, 62 | Instrumentation.class); 63 | // java 16 workaround 64 | StaticComponentContainer.Methods.setAccessible(agentMainMethod, true); 65 | agentMainMethod.invoke(null, "", InstrumentationSavingAgent.getInstrumentation()); 66 | /* 67 | * causes java 16 module errors inside 68 | * org.springframework.boot.devtools.restart.RestartLauncher 69 | * 70 | */ 71 | // AgentAccessor.agentmain("", InstrumentationSavingAgent.getInstrumentation()); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/java/com/sample/api/server/config/ApplicationConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.sample.api.server.config; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | import lombok.Data; 7 | 8 | @Data 9 | @Configuration 10 | @ConfigurationProperties 11 | public class ApplicationConfiguration { 12 | 13 | 14 | } 15 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/java/com/sample/api/server/config/AsyncConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.sample.api.server.config; 2 | 3 | import java.util.concurrent.Executor; 4 | 5 | import org.springframework.context.annotation.AdviceMode; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.scheduling.annotation.AsyncConfigurer; 8 | import org.springframework.scheduling.annotation.EnableAsync; 9 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 10 | 11 | @Configuration 12 | @EnableAsync(mode = AdviceMode.ASPECTJ) 13 | public class AsyncConfiguration implements AsyncConfigurer { 14 | 15 | @Override 16 | public Executor getAsyncExecutor() { 17 | ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 18 | executor.setCorePoolSize(1); 19 | executor.setMaxPoolSize(1); 20 | executor.setQueueCapacity(10); 21 | executor.setThreadNamePrefix("async-task-"); 22 | executor.initialize(); 23 | 24 | return executor; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/java/com/sample/api/server/config/CacheConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.sample.api.server.config; 2 | 3 | import org.springframework.cache.annotation.EnableCaching; 4 | import org.springframework.context.annotation.AdviceMode; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | @EnableCaching(mode = AdviceMode.ASPECTJ) 9 | public class CacheConfiguration { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/java/com/sample/api/server/config/LoadTimeWeavingConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.sample.api.server.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.context.annotation.EnableLoadTimeWeaving; 5 | import org.springframework.context.annotation.EnableLoadTimeWeaving.AspectJWeaving; 6 | 7 | @Configuration 8 | @EnableLoadTimeWeaving(aspectjWeaving = AspectJWeaving.ENABLED) 9 | public class LoadTimeWeavingConfiguration { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/java/com/sample/api/server/core/dto/UserDTO.java: -------------------------------------------------------------------------------- 1 | package com.sample.api.server.core.dto; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class UserDTO { 7 | 8 | private Integer userId; 9 | 10 | private String name; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/java/com/sample/api/server/core/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.sample.api.server.core.service; 2 | 3 | import com.sample.api.server.core.dto.UserDTO; 4 | 5 | public interface UserService { 6 | 7 | void save(UserDTO user); 8 | 9 | UserDTO getById(Integer userId); 10 | } 11 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/java/com/sample/api/server/core/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.sample.api.server.core.service.impl; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.springframework.cache.annotation.Cacheable; 7 | import org.springframework.scheduling.annotation.Async; 8 | import org.springframework.stereotype.Service; 9 | 10 | import com.sample.api.server.core.dto.UserDTO; 11 | import com.sample.api.server.core.service.UserService; 12 | 13 | import lombok.extern.slf4j.Slf4j; 14 | 15 | @Service 16 | @Slf4j 17 | public class UserServiceImpl implements UserService { 18 | private final List list = new ArrayList<>(); 19 | 20 | static { 21 | System.out.println("UserServiceImpl loaded"); 22 | } 23 | 24 | @Async 25 | @Override 26 | public void save(final UserDTO user) { 27 | user.setUserId(list.size() + 1); 28 | list.add(user); 29 | 30 | log.info("Added successfully."); 31 | } 32 | 33 | @Override 34 | @Cacheable("userCache") 35 | public UserDTO getById(final Integer userId) { 36 | return list.stream().filter(user -> user.getUserId() == userId).findFirst().get(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/java/com/sample/api/server/test/TestAspect.java: -------------------------------------------------------------------------------- 1 | package com.sample.api.server.test; 2 | 3 | import org.aspectj.lang.ProceedingJoinPoint; 4 | import org.aspectj.lang.annotation.Around; 5 | import org.aspectj.lang.annotation.Aspect; 6 | 7 | @Aspect 8 | public class TestAspect { 9 | 10 | public static boolean aspectWorked = false; 11 | 12 | @Around("execution(* *(..)) && @annotation(com.sample.api.server.test.TestAspectAnnotation)") 13 | public Object eventDispatchThread(final ProceedingJoinPoint pjp) throws Throwable { 14 | aspectWorked = true; 15 | return pjp.proceed(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/java/com/sample/api/server/test/TestAspectAnnotation.java: -------------------------------------------------------------------------------- 1 | package com.sample.api.server.test; 2 | 3 | public @interface TestAspectAnnotation { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/java/com/sample/api/server/test/TestAspectUseCase.java: -------------------------------------------------------------------------------- 1 | package com.sample.api.server.test; 2 | 3 | public class TestAspectUseCase { 4 | 5 | static { 6 | System.out.println("TestAspectUseCase.static"); 7 | } 8 | 9 | public void testAspect() { 10 | testAspectAnnotated(); 11 | if (!TestAspect.aspectWorked) { 12 | throw new IllegalStateException("Aspect did not work!"); 13 | } else { 14 | System.out.println("Aspect worked!"); 15 | } 16 | } 17 | 18 | @TestAspectAnnotation 19 | private void testAspectAnnotated() { 20 | System.out.println("TestAspectUseCase.testAspectAnnotated"); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/java/com/sample/api/server/web/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.sample.api.server.web.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.PathVariable; 6 | import org.springframework.web.bind.annotation.PostMapping; 7 | import org.springframework.web.bind.annotation.RequestBody; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | import com.sample.api.server.core.dto.UserDTO; 12 | import com.sample.api.server.core.service.UserService; 13 | 14 | @RestController 15 | @RequestMapping("/api/users") 16 | public class UserController { 17 | 18 | @Autowired 19 | private UserService userService; 20 | 21 | @PostMapping 22 | public UserDTO addUser(@RequestBody UserDTO user) { 23 | userService.save(user); 24 | return user; 25 | } 26 | 27 | @GetMapping("/{userId}") 28 | public UserDTO addUser(@PathVariable Integer userId) { 29 | return userService.getById(userId); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/java/lombok/launch/AgentAccessor.java: -------------------------------------------------------------------------------- 1 | package lombok.launch; 2 | 3 | import java.lang.instrument.Instrumentation; 4 | 5 | public class AgentAccessor { 6 | 7 | public static void agentmain(final String agentArgs, final Instrumentation instrumentation) throws Throwable { 8 | Agent.agentmain(agentArgs, instrumentation); 9 | } 10 | 11 | public static void premain(final String agentArgs, final Instrumentation instrumentation) throws Throwable { 12 | Agent.premain(agentArgs, instrumentation); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/resources/META-INF/aop.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # =============================== 2 | #=Server 3 | # =============================== 4 | server.port=8080 -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/resources/burningwave.static.properties: -------------------------------------------------------------------------------- 1 | banner.hide=true 2 | managed-logger.repository.enabled=false 3 | #avoiding the automatic call on startup of Burningwave Core to method 4 | #org.burningwave.core.assembler.StaticComponentContainer.Modules.exportAllToAll() 5 | #which exports all modules to all modules 6 | modules.export-all-to-all=false 7 | #prevent threads from spawning unnecessarily: https://github.com/burningwave/core/issues/10 8 | background-executor.all-tasks-monitoring.enabled=false 9 | static-component-container.on-close.close-all-component-containers=false 10 | static-component-container.on-close.close-file-system-helper=false -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/resources/ehcache.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 1 11 | 12 | 13 | 10 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 8 | 9 | 10 | 12 | 13 | ${pattern} 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/main/resources/lombok.config: -------------------------------------------------------------------------------- 1 | # Use slf4j 2 | lombok.log.apacheCommons.flagUsage=ERROR 3 | lombok.log.custom.flagUsage=ERROR 4 | lombok.log.flogger.flagUsage=ERROR 5 | lombok.log.jbosslog.flagUsage=ERROR 6 | lombok.log.javaUtilLogging.flagUsage=ERROR 7 | lombok.log.log4j.flagUsage=ERROR 8 | lombok.log.log4j2.flagUsage=ERROR 9 | lombok.log.xslf4j.flagUsage=ERROR 10 | 11 | # warning some annotations. 12 | #lombok.sneakyThrows.flagUsage=WARNING 13 | 14 | # Set equalsAndHashCode 15 | lombok.equalsAndHashCode.callSuper=call 16 | 17 | # Set toString 18 | lombok.toString.callSuper=call 19 | 20 | # workaround for https://github.com/FasterXML/jackson-databind/issues/1122 21 | # @ConstructorProperties conflicts with the field, that has @JsonProperty. 22 | lombok.anyConstructor.suppressConstructorProperties = true -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/test/java/com/sample/api/server/core/service/AbstractTestCase.java: -------------------------------------------------------------------------------- 1 | package com.sample.api.server.core.service; 2 | 3 | import org.junit.jupiter.api.BeforeAll; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | import de.invesdwin.instrument.DynamicInstrumentationLoader; 7 | 8 | @SpringBootTest 9 | public class AbstractTestCase { 10 | 11 | @BeforeAll 12 | static void beforeAll() { 13 | DynamicInstrumentationLoader.waitForInitialized(); 14 | DynamicInstrumentationLoader.initLoadTimeWeavingContext(); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /tests/springboot-devtools-testapp/src/test/java/com/sample/api/server/core/service/UserServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.sample.api.server.core.service; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | 6 | import com.sample.api.server.core.dto.UserDTO; 7 | 8 | import lombok.extern.slf4j.Slf4j; 9 | 10 | @Slf4j 11 | class UserServiceTest extends AbstractTestCase { 12 | 13 | @Autowired 14 | private UserService userServices; 15 | 16 | @Test 17 | void getById() { 18 | UserDTO byId = userServices.getById(1); 19 | log.info("Result: {}", byId); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /tests/springboot-instrumentation-testapp/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /.classpath 3 | /.project 4 | /.settings/ 5 | /.factorypath -------------------------------------------------------------------------------- /tests/springboot-instrumentation-testapp/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.5.1 9 | 10 | 11 | 4.0.0 12 | de.invesdwin 13 | springboot-instrumentation-testapp 14 | 0.0.1-SNAPSHOT 15 | 16 | de.invesdwin.springboot.instrumentation.testapp.Main 17 | 2.5.1 18 | 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-maven-plugin 25 | ${version.spring-boot-maven-plugin} 26 | 27 | 28 | 29 | 30 | 31 | de.invesdwin 32 | invesdwin-instrument 33 | 1.0.15-SNAPSHOT 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-maven-plugin 38 | ${version.spring-boot-maven-plugin} 39 | compile 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /tests/springboot-instrumentation-testapp/src/main/java/de/invesdwin/springboot/instrumentation/testapp/Main.java: -------------------------------------------------------------------------------- 1 | package de.invesdwin.springboot.instrumentation.testapp; 2 | 3 | import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver; 4 | 5 | import de.invesdwin.instrument.DynamicInstrumentationLoader; 6 | 7 | public class Main { 8 | public static void main(String[] args) { 9 | DynamicInstrumentationLoader.waitForInitialized(); 10 | DynamicInstrumentationLoader.initLoadTimeWeavingContext(); 11 | if (!InstrumentationLoadTimeWeaver.isInstrumentationAvailable()) { 12 | throw new IllegalStateException("Instrumentation not available!"); 13 | } else { 14 | System.out.println("Instrumentation available!"); 15 | } 16 | } 17 | } --------------------------------------------------------------------------------