├── .gitignore
├── LICENSE
├── README.md
├── custom-plugin
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── org
│ │ └── hotswap
│ │ └── agent
│ │ └── example
│ │ ├── RunPlugin.java
│ │ ├── plugin
│ │ ├── ExamplePlugin.java
│ │ ├── ReloadClassCommand.java
│ │ └── ReloadClassService.java
│ │ └── service
│ │ └── HelloWorldService.java
│ └── resources
│ ├── examplePlugin.resource
│ └── hotswap-agent.properties
├── cxf
├── cxf-jaxrs-spring
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── org
│ │ │ └── hotswap
│ │ │ └── agent
│ │ │ └── plugin
│ │ │ └── cxf
│ │ │ └── spring
│ │ │ └── jaxrs
│ │ │ ├── Service1.java
│ │ │ ├── Service2.java
│ │ │ └── ServiceEndpoint.java
│ │ └── webapp
│ │ ├── META-INF
│ │ └── context.xml
│ │ └── WEB-INF
│ │ ├── beans.xml
│ │ └── web.xml
└── cxf-jaxrs
│ ├── pom.xml
│ └── src
│ └── main
│ ├── java
│ └── org
│ │ └── hotswap
│ │ └── agent
│ │ └── example
│ │ └── cxf
│ │ └── jaxrs
│ │ ├── AcceptPerson.java
│ │ ├── Person.java
│ │ ├── Service1.java
│ │ ├── Service2.java
│ │ ├── ServiceEndpoint.java
│ │ └── StatelessBean.java
│ └── webapp
│ ├── META-INF
│ └── context.xml
│ └── WEB-INF
│ ├── beans.xml
│ └── web.xml
├── deltaspike-hibernate-jsf
├── Dockerfile
├── buildAndRunDebug.sh
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── org
│ │ └── hotswap
│ │ └── agent
│ │ └── example
│ │ └── deltaspike
│ │ ├── ContextListener.java
│ │ ├── appl
│ │ ├── MasterDetailControllerBase.java
│ │ └── UserController.java
│ │ ├── beans
│ │ ├── ApplicationBean.java
│ │ ├── GroupedConvBean1.java
│ │ ├── GroupedConvBean2.java
│ │ ├── GroupedConvBean3.java
│ │ ├── HelloProducer1.java
│ │ ├── HelloProducer2.java
│ │ ├── JsfViewBean.java
│ │ ├── ManagedBean.java
│ │ ├── MyConversationGroup.java
│ │ ├── OmniViewBean.java
│ │ ├── SessionBean.java
│ │ └── WindowBean.java
│ │ ├── em
│ │ ├── EntityManagerFactoryProducer.java
│ │ └── EntityManagerProducer.java
│ │ ├── enums
│ │ ├── UserRole.java
│ │ └── UserRoleConverter.java
│ │ ├── forms
│ │ ├── LoginForm.java
│ │ └── UserForm.java
│ │ ├── jpa
│ │ ├── User.java
│ │ └── UserRepository.java
│ │ └── jsf
│ │ ├── AppJsfModuleConfig.java
│ │ ├── Messages.java
│ │ └── Pages.java
│ ├── resources
│ ├── META-INF
│ │ ├── beans.xml
│ │ ├── openwebbeans
│ │ │ └── openwebbeans.properties
│ │ └── persistence.xml
│ ├── hotswap-agent.properties
│ └── messages_en.properties
│ └── webapp
│ ├── META-INF
│ ├── MANIFEST.MF
│ └── context.xml
│ ├── WEB-INF
│ ├── beans.xml
│ ├── faces-config.xml
│ └── web.xml
│ ├── appl
│ ├── beans.xhtml
│ └── users.xhtml
│ ├── errorpages
│ ├── error.xhtml
│ ├── lowPriviliges.xhtml
│ ├── notFound.xhtml
│ └── viewExpired.xhtml
│ ├── include
│ ├── header.xhtml
│ └── menu.xhtml
│ ├── index.xhtml
│ └── resources
│ └── css
│ └── default.css
├── gae
├── .gitignore
├── .idea
│ └── codeStyleSettings.xml
├── LICENSE
├── README.md
├── ear
│ ├── appengine-maven-plugin.txt
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── application
│ │ └── META-INF
│ │ ├── appengine-application.xml
│ │ └── application.xml
├── gae-backend
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── google
│ │ │ └── developers
│ │ │ ├── BackendServlet.java
│ │ │ ├── BackendServletModule.java
│ │ │ └── BackendStartupListener.java
│ │ └── webapp
│ │ ├── WEB-INF
│ │ ├── appengine-web.xml
│ │ ├── logging.properties
│ │ └── web.xml
│ │ ├── api
│ │ └── 5xx
│ │ │ └── index.jsp
│ │ └── index.html
├── gae-default
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── google
│ │ │ ├── developers
│ │ │ ├── DefaultServletModule.java
│ │ │ ├── DefaultStartupListener.java
│ │ │ ├── Path.java
│ │ │ └── UnauthorizedServlet.java
│ │ │ └── training
│ │ │ └── helloworld
│ │ │ ├── Constants.java
│ │ │ ├── HelloClass.java
│ │ │ └── HelloWorldEndpoints.java
│ │ └── webapp
│ │ ├── WEB-INF
│ │ ├── appengine-web.xml
│ │ ├── cron.xml
│ │ ├── logging.properties
│ │ └── web.xml
│ │ └── api
│ │ └── 5xx
│ │ └── index.jsp
├── pom.xml
└── shared
│ ├── pom.xml
│ └── src
│ └── main
│ └── java
│ └── com
│ └── google
│ └── developers
│ ├── DevelopersSharedFilter.java
│ ├── DevelopersSharedModule.java
│ ├── DevelopersSharedServletModule.java
│ ├── ModuleStartServlet.java
│ └── PropertiesContant.java
├── hotswap-agent-examples-servlet-parent
├── README.md
└── pom.xml
├── jersey1
├── README.md
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── org
│ │ └── hotswap
│ │ └── agent
│ │ └── exemple
│ │ └── jersey
│ │ └── Jersey1Resource.java
│ └── webapp
│ └── WEB-INF
│ └── web.xml
├── jersey2-jetty-hk2
├── README.md
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── org
│ │ └── hotswap
│ │ └── agent
│ │ └── example
│ │ └── jersey
│ │ ├── Jersey2App.java
│ │ ├── Jersey2Resource.java
│ │ ├── MyApplication.java
│ │ ├── MyApplicationBinder.java
│ │ ├── TestService.java
│ │ ├── TestService2.java
│ │ └── TestService3.java
│ └── webapp
│ └── WEB-INF
│ └── web.xml
├── jersey2
├── README.md
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── org
│ │ └── hotswap
│ │ └── agent
│ │ └── exemple
│ │ └── jersey
│ │ └── Jersey2Resource.java
│ └── webapp
│ └── WEB-INF
│ └── web.xml
├── plain-java
├── README.md
├── pom.xml
├── run-tests.sh
└── src
│ ├── main
│ ├── java-extra
│ │ └── org
│ │ │ └── hotswap
│ │ │ └── agent
│ │ │ └── example
│ │ │ ├── HelloAnnotation.java
│ │ │ ├── HelloInterface.java
│ │ │ ├── HelloWorld.java
│ │ │ └── HelloWorldHotswap.java
│ ├── java-hotswap
│ │ └── org
│ │ │ └── hotswap
│ │ │ └── agent
│ │ │ └── example
│ │ │ ├── HelloAnnotation.java
│ │ │ ├── HelloInterface.java
│ │ │ └── HelloWorldHotswap.java
│ ├── java
│ │ └── org
│ │ │ └── hotswap
│ │ │ └── agent
│ │ │ └── example
│ │ │ ├── HelloAnnotation.java
│ │ │ ├── HelloInterface.java
│ │ │ ├── HelloWorld.java
│ │ │ └── HelloWorldHotswap.java
│ ├── resources-extra
│ │ └── test.properties
│ ├── resources-watch
│ │ ├── testWatch.properties
│ │ └── testWatchReplace.properties
│ └── resources
│ │ ├── hotswap-agent.properties
│ │ ├── test.properties
│ │ └── testWatch.properties
│ └── test
│ └── java
│ └── org
│ └── hotswap
│ └── agent
│ └── example
│ ├── HelloWorldHotswapTest.java
│ └── HelloWorldTest.java
├── plain-servlet
├── README.md
├── pom.xml
├── run-tests.sh
└── src
│ ├── main
│ ├── java-extra
│ │ └── org
│ │ │ └── hotswap
│ │ │ └── agent
│ │ │ └── example
│ │ │ ├── HelloWorldBaseServlet.java
│ │ │ ├── HelloWorldServlet.java
│ │ │ └── HelloWorldServletHotswap.java
│ ├── java-hotswap
│ │ └── org
│ │ │ └── hotswap
│ │ │ └── agent
│ │ │ └── example
│ │ │ ├── HelloWorldBaseServlet.java
│ │ │ └── HelloWorldServletHotswap.java
│ ├── java
│ │ └── org
│ │ │ └── hotswap
│ │ │ └── agent
│ │ │ └── example
│ │ │ ├── HelloWorldBaseServlet.java
│ │ │ ├── HelloWorldServlet.java
│ │ │ └── HelloWorldServletHotswap.java
│ ├── resources-extra
│ │ └── test.properties
│ ├── resources-watch
│ │ ├── testWatch.properties
│ │ └── testWatchReplace.properties
│ ├── resources
│ │ ├── hotswap-agent.properties
│ │ ├── test.properties
│ │ └── testWatch.properties
│ ├── webapp-extra
│ │ └── hello.jsp
│ └── webapp
│ │ ├── META-INF
│ │ └── context.xml
│ │ ├── WEB-INF
│ │ ├── jboss-web.xml
│ │ └── web.xml
│ │ └── hello.jsp
│ └── test
│ └── java
│ └── org
│ └── hotswap
│ └── agent
│ └── example
│ ├── HelloWorldServletHotswapIT.java
│ ├── HelloWorldServletIT.java
│ └── HelloWorldServletJspIT.java
├── pom.xml
├── resteasy-app
├── pom.xml
├── resteasy-managment
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── org
│ │ │ │ └── hotswap
│ │ │ │ └── agent
│ │ │ │ └── example
│ │ │ │ └── service
│ │ │ │ ├── BaseApplication.java
│ │ │ │ └── PersonManagement.java
│ │ └── webapp
│ │ │ ├── WEB-INF
│ │ │ ├── jboss-web.xml
│ │ │ └── web.xml
│ │ │ ├── index.jsp
│ │ │ └── jboss-web.xml
│ │ └── test
│ │ └── java
│ │ └── org
│ │ └── hotswap
│ │ └── agent
│ │ └── example
│ │ └── test
│ │ └── JSONIgnorePropTest.java
└── resteasy-model
│ ├── pom.xml
│ └── src
│ └── main
│ └── java
│ └── org
│ └── hotswap
│ └── agent
│ └── example
│ └── model
│ ├── Person.java
│ └── PersonModelBase.java
├── run-tests.sh
├── spring-boot-kotlin
├── Dockerfile
├── README.md
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── hotswap
│ │ │ └── agent
│ │ │ └── example
│ │ │ └── springbootkotlin
│ │ │ ├── ExampleApi.kt
│ │ │ └── ExampleApplication.kt
│ └── resources
│ │ └── application.yml
│ └── test
│ └── resources
│ └── application.yml
├── spring-boot
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── hotswap
│ │ │ └── agent
│ │ │ └── example
│ │ │ └── springboot
│ │ │ ├── HotswapSpringBoot.java
│ │ │ ├── TestPojo.java
│ │ │ ├── TestPojo2.java
│ │ │ ├── TestRest.java
│ │ │ └── TestRest2.java
│ └── resources
│ │ ├── application.properties
│ │ └── hotswap-agent.properties
│ └── test
│ └── java
│ └── org
│ └── hotswap
│ └── agent
│ └── example
│ └── springboot
│ ├── BasicSpringBootTest.java
│ └── RestTest.java
└── spring-hibernate
├── README.md
├── pom.xml
├── runtime
└── data
│ ├── agent-test.hsqldb.lck
│ ├── agent-test.hsqldb.properties
│ └── agent-test.hsqldb.script
└── src
├── main
├── java-extra
│ └── org
│ │ └── hotswap
│ │ └── agent
│ │ └── examples
│ │ └── plain
│ │ ├── HelloWorld.java
│ │ └── HelloWorldHotswap.java
├── java-hotswap
│ └── org
│ │ └── hotswap
│ │ └── agent
│ │ └── examples
│ │ └── service
│ │ └── TestRepository.java
├── java
│ └── org
│ │ └── hotswap
│ │ └── agent
│ │ └── example
│ │ ├── model
│ │ └── TestEntity.java
│ │ ├── mvc
│ │ └── IndexController.java
│ │ └── service
│ │ ├── TestEntityService.java
│ │ └── TestRepository.java
├── resources-extra
│ └── test.properties
├── resources-watch
│ ├── testWatch.properties
│ └── testWatchReplace.properties
├── resources
│ ├── META-INF
│ │ └── persistence.xml
│ ├── examplePlugin.resource
│ ├── hotswap-agent.properties
│ └── test.resource
└── webapp
│ ├── META-INF
│ └── context.xml
│ ├── WEB-INF
│ ├── AgentWeb-servlet.xml
│ ├── jboss-web.xml
│ ├── jetty-env.xml
│ ├── jsp
│ │ └── test.jsp
│ ├── spring
│ │ ├── applicationContext-jpa.xml
│ │ └── applicationContext-service.xml
│ └── web.xml
│ └── index.jsp
└── test
└── java
└── org
└── hotswap
└── agent
└── example
└── mvc
└── IndexControllerIT.java
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 |
3 | #IntelliJ
4 | .idea
5 | *.iml
6 |
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | HotswapAgent example applications
2 | =================================
3 |
4 | Example applications for HotswapAgent plugins.
5 |
6 | The purpose of an example application is:
7 | * complex automate integration tests (check various configurations before a release, see `run-tests.sh` script)
8 | * to check "real world" plugin usage during plugin development (i.e. inside container)
9 | * to provide working solution for typical application setups
10 | * sandbox to simulate issues for existing or new setups
11 |
12 | Feel free to fork/branch and create an application for your setup (functional, but as simple as possible).
13 | General setups will be merged into the master.
14 |
15 | # plain-java
16 | This example uses only core agent library and runs without any framework support. Check this example
17 | to learn basic agent properties usage (extraClasspath, watchResources, autoHotswap).
18 |
19 | # plain-servlet
20 | Run hotwap agent with a servlet container/J2EE server (Jetty/Tomcat/JBoss). This example does pretty the same
21 | as plain-java, but checks the value as HTTP response strings. This examples checks also that various application
22 | server versions are supported.
23 |
24 | # custom-plugin
25 | Detail explanation and example of how to create custom plugin even inside your application.
26 |
27 | # spring-hibernate
28 | Complex project with typical setup Spring + Spring MVC + Hibernate.
29 |
30 | # seam-hibernate-jsf
31 |
32 | # cdi-hibernate-jsf
33 |
--------------------------------------------------------------------------------
/custom-plugin/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | jar
7 |
8 |
9 | org.hotswapagent
10 | hotswap-agent-examples-aggregator
11 | 1.4.2-SNAPSHOT
12 |
13 |
14 | org.hotswap.plugin.examples
15 | custom-plugin
16 |
17 |
18 |
19 | org.hotswapagent
20 | hotswap-agent-core
21 | ${project.version}
22 | provided
23 |
24 |
25 |
26 | junit
27 | junit
28 | 4.12
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | org.apache.maven.plugins
37 | maven-jar-plugin
38 |
39 |
40 |
41 | true
42 | org.hotswap.agent.example.RunPlugin
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/custom-plugin/src/main/java/org/hotswap/agent/example/RunPlugin.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | import org.hotswap.agent.example.service.HelloWorldService;
4 |
5 | public class RunPlugin {
6 | public static void main(String[] args) throws InterruptedException {
7 | HelloWorldService helloWorldService = new HelloWorldService();
8 | while(true) {
9 | System.out.print(helloWorldService.getExamplePluginResourceText());
10 | System.out.print(",");
11 | System.out.print(helloWorldService.getLoadedClasses());
12 | System.out.print(",");
13 | System.out.print(helloWorldService.getReloadedClasses());
14 | System.out.println(";");
15 | Thread.sleep(1000);
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/custom-plugin/src/main/java/org/hotswap/agent/example/plugin/ReloadClassCommand.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.plugin;
2 |
3 | import org.hotswap.agent.command.MergeableCommand;
4 | import org.hotswap.agent.logging.AgentLogger;
5 |
6 | import java.lang.reflect.Method;
7 |
8 | /**
9 | * A command to merge multiple reload events into one execution and execute the logic in application classloader.
10 | */
11 | public class ReloadClassCommand extends MergeableCommand {
12 | private static AgentLogger LOGGER = AgentLogger.getLogger(ReloadClassCommand.class);
13 | ClassLoader appClassLoader;
14 | String className;
15 | Object testEnityService;
16 |
17 | /**
18 | * @param appClassLoader Usually you need the application classloader as a parameter - to know in which
19 | * classloader the class you want to call lives
20 | * @param className reloaded className
21 | * @param testEnityService the target service registered with the plugin - not that we are still in the
22 | * plugin classloader and the service cannot be typed to agentexamples's class.
23 | */
24 | public ReloadClassCommand(ClassLoader appClassLoader, String className, Object testEnityService) {
25 | this.appClassLoader = appClassLoader;
26 | this.className = className;
27 | this.testEnityService = testEnityService;
28 | }
29 |
30 | @Override
31 | public void executeCommand() {
32 | try {
33 | // Now we have application classloader and the service on which to invoke the method, we can use
34 | // reflection directly
35 | // but for demonstration purpose we invoke a plugin class, that lives in the application classloader
36 | Method setExamplePluginResourceText = appClassLoader.loadClass(ReloadClassService.class.getName())
37 | .getDeclaredMethod("classReloaded", String.class, Object.class);
38 | setExamplePluginResourceText.invoke(null, className, testEnityService);
39 | } catch (Exception e) {
40 | LOGGER.error("Error invoking {}.reload()", e, ReloadClassService.class.getName());
41 | }
42 |
43 | }
44 |
45 | /**
46 | * Use equals to group "similar commands". If multiple "equals" commands are scheduled during
47 | * the scheduler timeout, only the last command is executed. If you need information regarding
48 | * all merged commands and/or select which is executed, use MergeableCommand superclass.
49 | */
50 | @Override
51 | public boolean equals(Object o) {
52 | if (this == o) return true;
53 | if (o == null || getClass() != o.getClass()) return false;
54 |
55 | ReloadClassCommand that = (ReloadClassCommand) o;
56 |
57 | if (!className.equals(that.className)) return false;
58 |
59 | return true;
60 | }
61 |
62 | @Override
63 | public int hashCode() {
64 | return className.hashCode();
65 | }
66 |
67 | @Override
68 | public String toString() {
69 | return "ReloadClassCommand{" +
70 | "className='" + className + '\'' +
71 | ", helloWorldService=" + testEnityService +
72 | '}';
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/custom-plugin/src/main/java/org/hotswap/agent/example/plugin/ReloadClassService.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.plugin;
2 |
3 | import org.hotswap.agent.example.service.HelloWorldService;
4 |
5 | /**
6 | * This class should be used in the application classloader.
7 | *
8 | * Hotswap agent defines plugin classes in BOTH classloaders agent AND application. You need to know for which
9 | * classloader is each class targeted. In this example plugin, this is the only class targeted towards application
10 | * classloader.
11 | */
12 | public class ReloadClassService {
13 | /**
14 | * Method invoked from ReloadClassCommand using reflection in application classloader.
15 | *
16 | * @param className class name
17 | * @param helloWorldServiceObject object originally from the application, registered in the plugin. It is from
18 | * application classloader and hence cannot be typed in plugin classloader. Now
19 | * we are back in application classloader and can safely cast back to it's type.
20 | */
21 | public static void classReloaded(String className, Object helloWorldServiceObject) {
22 |
23 | // this is the main purpose of this class. Finally, we can use typed variables and
24 | // use normal code instead of reflection. Imagine more complex code to reload part of your
25 | // framework - it would be inconvenient to use reflection for each invocation.
26 | HelloWorldService helloWorldService = (HelloWorldService) helloWorldServiceObject;
27 |
28 | // call framework method directly
29 | helloWorldService.addReloadedClass(className);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/custom-plugin/src/main/java/org/hotswap/agent/example/service/HelloWorldService.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.service;
2 |
3 | import java.util.HashSet;
4 | import java.util.Set;
5 |
6 | /**
7 | * Example service which is watched for changes and invoked from the plugin.
8 | */
9 | public class HelloWorldService {
10 | // Add each reloaded class (by hotswap or watcher)
11 | Set reloadedClasses = new HashSet();
12 |
13 | // count of loaded classes
14 | int loadedClasses;
15 |
16 | // text from examplePlugin.resource, it should be automatically updated after the resource is modified
17 | String examplePluginResourceText;
18 |
19 | public String getExamplePluginResourceText() {
20 | return examplePluginResourceText;
21 | }
22 |
23 | public void setExamplePluginResourceText(String examplePluginResourceText) {
24 | this.examplePluginResourceText = examplePluginResourceText;
25 | }
26 |
27 | public int getLoadedClasses() {
28 | return loadedClasses;
29 | }
30 |
31 | public void setLoadedClasses(int loadedClasses) {
32 | this.loadedClasses = loadedClasses;
33 | }
34 |
35 | // reflection command currently supports only object types
36 | public void setLoadedClasses(Integer loadedClasses) {
37 | this.loadedClasses = loadedClasses;
38 | }
39 |
40 | public void addReloadedClass(String className) {
41 | reloadedClasses.add(className);
42 | }
43 |
44 | public Set getReloadedClasses() {
45 | return reloadedClasses;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/custom-plugin/src/main/resources/examplePlugin.resource:
--------------------------------------------------------------------------------
1 | Change this file and see the result in TestEntityService.helloWorld()
--------------------------------------------------------------------------------
/custom-plugin/src/main/resources/hotswap-agent.properties:
--------------------------------------------------------------------------------
1 | pluginPackages=org.hotswap.agent.example.plugin
2 |
3 | watchResources=src/main/resources
4 |
5 | # uncomment to test autohotswap feature
6 | #autoHotswap=true
7 |
8 | LOGGER.org.hotswap.agent=DEBUG
9 | LOGGER.org.hotswap.agent.plugin=TRACE
10 |
--------------------------------------------------------------------------------
/cxf/cxf-jaxrs-spring/src/main/java/org/hotswap/agent/plugin/cxf/spring/jaxrs/Service1.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.plugin.cxf.spring.jaxrs;
2 |
3 | import org.springframework.stereotype.Service;
4 |
5 | @Service
6 | public class Service1 {
7 | void doSomething() {
8 | System.out.println("Service1 print");
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/cxf/cxf-jaxrs-spring/src/main/java/org/hotswap/agent/plugin/cxf/spring/jaxrs/Service2.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.plugin.cxf.spring.jaxrs;
2 |
3 | import org.springframework.stereotype.Service;
4 |
5 | @Service
6 | public class Service2 {
7 | void doSomething() {
8 | System.out.println("Service2 print");
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/cxf/cxf-jaxrs-spring/src/main/java/org/hotswap/agent/plugin/cxf/spring/jaxrs/ServiceEndpoint.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.plugin.cxf.spring.jaxrs;
2 |
3 | import javax.ws.rs.GET;
4 | import javax.ws.rs.Path;
5 | import javax.ws.rs.Produces;
6 | import javax.ws.rs.QueryParam;
7 | import javax.ws.rs.core.MediaType;
8 | import javax.ws.rs.core.Response;
9 |
10 | import org.springframework.beans.factory.annotation.Autowired;
11 |
12 | @Path("/services")
13 | public class ServiceEndpoint {
14 |
15 | @Autowired
16 | private Service1 service1;
17 |
18 | @Autowired
19 | private Service2 service2;
20 |
21 | @Path("/service1")
22 | @GET
23 | @Produces(MediaType.TEXT_PLAIN)
24 | public Response service1(@QueryParam("echo") final String payload) {
25 | service2.doSomething();
26 | return Response.ok(payload).build();
27 | }
28 |
29 | // @Path("/service2")
30 | // @GET
31 | // @Produces(MediaType.APPLICATION_JSON)
32 | // public Response service2() {
33 | // service1.doSomething();
34 | // return Response.ok().build();
35 | // }
36 | }
37 |
--------------------------------------------------------------------------------
/cxf/cxf-jaxrs-spring/src/main/webapp/META-INF/context.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/cxf/cxf-jaxrs-spring/src/main/webapp/WEB-INF/beans.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/cxf/cxf-jaxrs-spring/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | JAX-RS Simple Service
4 | JAX-RS Simple Service
5 |
6 | contextConfigLocation
7 | WEB-INF/beans.xml
8 |
9 |
10 | org.springframework.web.context.ContextLoaderListener
11 |
12 |
13 | CXFServlet
14 | org.apache.cxf.transport.servlet.CXFServlet
15 | 1
16 |
17 |
18 | CXFServlet
19 | /*
20 |
21 |
22 |
--------------------------------------------------------------------------------
/cxf/cxf-jaxrs/src/main/java/org/hotswap/agent/example/cxf/jaxrs/AcceptPerson.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.cxf.jaxrs;
2 |
3 | import javax.xml.bind.annotation.XmlElement;
4 |
5 | public class AcceptPerson {
6 | @XmlElement
7 | String accepted;
8 |
9 | public String getAccepted() {
10 | return accepted;
11 | }
12 |
13 | public void setAccepted(String accepted) {
14 | this.accepted = accepted;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/cxf/cxf-jaxrs/src/main/java/org/hotswap/agent/example/cxf/jaxrs/Person.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.cxf.jaxrs;
2 |
3 | import javax.xml.bind.annotation.XmlElement;
4 | import javax.xml.bind.annotation.XmlRootElement;
5 |
6 | @XmlRootElement
7 | public class Person {
8 | String firstName;
9 | String lastName;
10 | Integer phoneNumber;
11 | String email;
12 | String unknown;
13 |
14 | @XmlElement
15 | public String getFirstName() {
16 | return firstName;
17 | }
18 |
19 | public void setFirstName(String firstName) {
20 | this.firstName = firstName;
21 | }
22 |
23 | @XmlElement
24 | public String getLastName() {
25 | return lastName;
26 | }
27 |
28 | public void setLastName(String lastName) {
29 | this.lastName = lastName;
30 | }
31 |
32 | @XmlElement
33 | public Integer getPhoneNumber() {
34 | return phoneNumber;
35 | }
36 |
37 | public void setPhoneNumber(Integer phoneNumber) {
38 | this.phoneNumber = phoneNumber;
39 | }
40 |
41 | @XmlElement
42 | public String getEmail() {
43 | return email;
44 | }
45 |
46 | public void setEmail(String email) {
47 | this.email = email;
48 | }
49 | public String getUnknown() {
50 | return unknown;
51 | }
52 |
53 | public void setUnknown(String unknown) {
54 | this.unknown = unknown;
55 | }
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/cxf/cxf-jaxrs/src/main/java/org/hotswap/agent/example/cxf/jaxrs/Service1.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.cxf.jaxrs;
2 |
3 | public class Service1 {
4 | void doSomething() {
5 | System.out.println("Service1 print");
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/cxf/cxf-jaxrs/src/main/java/org/hotswap/agent/example/cxf/jaxrs/Service2.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.cxf.jaxrs;
2 |
3 | public class Service2 {
4 | void doSomething() {
5 | System.out.println("Service2 print");
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/cxf/cxf-jaxrs/src/main/java/org/hotswap/agent/example/cxf/jaxrs/ServiceEndpoint.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.cxf.jaxrs;
2 |
3 | import java.util.UUID;
4 |
5 | import javax.inject.Inject;
6 | import javax.ws.rs.Consumes;
7 | import javax.ws.rs.GET;
8 | import javax.ws.rs.POST;
9 | import javax.ws.rs.Path;
10 | import javax.ws.rs.Produces;
11 | import javax.ws.rs.QueryParam;
12 | import javax.ws.rs.core.MediaType;
13 | import javax.ws.rs.core.Response;
14 |
15 | @Path("/services")
16 | public class ServiceEndpoint {
17 |
18 | @Inject
19 | private Service1 service1;
20 |
21 | @Inject
22 | private Service2 service2;
23 |
24 | @Inject
25 | private StatelessBean statelessBean;
26 |
27 | public ServiceEndpoint() {
28 | super();
29 | }
30 |
31 | @Path("/service1")
32 | @GET
33 | @Produces(MediaType.TEXT_PLAIN)
34 | public Response service1(@QueryParam("echo") final String payload) {
35 | service2.doSomething();
36 | return Response.ok(payload).build();
37 | }
38 |
39 | @Path("/service2")
40 | @GET
41 | @Produces(MediaType.APPLICATION_JSON)
42 | public Response service2() {
43 | service1.doSomething();
44 | return Response.ok().build();
45 | }
46 |
47 | @Path("/person")
48 | @POST
49 | @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
50 | @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
51 | public AcceptPerson action(Person person) throws Exception {
52 | if (person != null) {
53 | AcceptPerson response = new AcceptPerson();
54 | response.setAccepted("Done.");
55 | return response;
56 | }
57 | return null;
58 | }
59 |
60 | @GET
61 | @Produces(MediaType.TEXT_PLAIN)
62 | @Path("simple")
63 | public Response getSimple() {
64 | //statistics.updateStatistic(0);
65 | return Response.ok(statelessBean.getHello()).build();
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/cxf/cxf-jaxrs/src/main/java/org/hotswap/agent/example/cxf/jaxrs/StatelessBean.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.cxf.jaxrs;
2 |
3 | import javax.ejb.Stateless;
4 |
5 | @Stateless
6 | public class StatelessBean {
7 |
8 | public String getHello() {
9 | return getHelloInt();
10 | }
11 |
12 | private String getHelloInt() {
13 | return "hello";
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/cxf/cxf-jaxrs/src/main/webapp/META-INF/context.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/cxf/cxf-jaxrs/src/main/webapp/WEB-INF/beans.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/cxf/cxf-jaxrs/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | JAX-RS Simple Service
4 | JAX-RS Simple Service
5 |
6 |
11 |
12 |
13 | org.jboss.weld.environment.servlet.Listener
14 |
15 |
16 |
17 | CXFServlet
18 | org.apache.cxf.cdi.CXFCdiServlet
19 | 1
20 |
21 |
22 |
23 |
24 | BeanManager
25 | javax.enterprise.inject.spi.BeanManager
26 |
27 |
28 |
29 | CXFServlet
30 | /*
31 |
32 |
33 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM hotswapagent/tomcat
2 | RUN mkdir -p /extra_class_path
3 | RUN mkdir -p /webapp_dir
4 | COPY ./target/deltaspike-hibernate-jsf-0.0.1-SNAPSHOT.war ${DEPLOYMENT_DIR}
5 | ENV JAVA_OPTS="-XXaltjvm=dcevm -agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=n -javaagent:/opt/hotswap-agent/hotswap-agent.jar -Dextra.class.path=/extra_class_path -Dwebapp.dir=/webapp_dir"
6 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/buildAndRunDebug.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | mvn clean package && docker build -t deltaspike-hibernate-jsf .
3 | docker run -ti --rm -p 8080:8080 -p 8000:8000 -v `pwd`/target/classes:/extra_class_path -v `pwd`/src/main/webapp:/webapp_dir -v /var/run/docker.sock:/var/run/docker.sock deltaspike-hibernate-jsf
4 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/ContextListener.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike;
2 |
3 | import javax.inject.Inject;
4 | import javax.persistence.EntityManagerFactory;
5 | import javax.servlet.ServletContextEvent;
6 | import javax.servlet.ServletContextListener;
7 |
8 | public class ContextListener implements ServletContextListener {
9 |
10 | // @Inject
11 | // private EntityManagerFactory emf;
12 |
13 | @Override
14 | public void contextDestroyed(ServletContextEvent arg0) {
15 | // Do nothing
16 | }
17 |
18 | @Override
19 | public void contextInitialized(ServletContextEvent arg0) {
20 | // initialize entity manager factory on application statup
21 | // emf.createEntityManager();
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/appl/MasterDetailControllerBase.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.appl;
2 |
3 | import java.io.Serializable;
4 |
5 | import javax.enterprise.context.Conversation;
6 | import javax.inject.Inject;
7 |
8 | import org.primefaces.event.SelectEvent;
9 |
10 | public abstract class MasterDetailControllerBase implements Serializable {
11 |
12 | private static final long serialVersionUID = 5824242841963664386L;
13 |
14 | protected static final int LIST_LEVEL = 1;
15 |
16 | protected static final int DETAIL_LEVEL = 2;
17 |
18 | private int detailLevel = LIST_LEVEL;
19 |
20 | private T detail;
21 |
22 | @Inject
23 | private Conversation conversation;
24 |
25 | public void clearDetail() {
26 | if (!conversation.isTransient()) {
27 | conversation.end();
28 | }
29 | }
30 |
31 | public void selectNewDetail() {
32 | selectDetail(null);
33 | }
34 |
35 | public void selectDetail(T detail) {
36 | this.detail = detail;
37 |
38 | if (!conversation.isTransient()) {
39 | conversation.end();
40 | }
41 | conversation.begin();
42 |
43 | onDetailSelected(detail);
44 | }
45 |
46 | @SuppressWarnings("unchecked")
47 | public void onSelectDetailEvent(SelectEvent event) {
48 | selectDetail((T) event.getObject());
49 | detailLevel = DETAIL_LEVEL;
50 | }
51 |
52 | public T getSelection() {
53 | return detail;
54 | }
55 |
56 | public void setSelection(T selection) {
57 | // Nothing to do
58 | }
59 |
60 | abstract protected void onDetailSelected(T detail);
61 |
62 | public T getDetail() {
63 | return detail;
64 | }
65 |
66 | protected void setDetail(T detail) {
67 | this.detail = detail;
68 | }
69 |
70 | public int getDetailLevel() {
71 | return detailLevel;
72 | }
73 |
74 | public void setDetailLevel(int detailLevel) {
75 | this.detailLevel = detailLevel;
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/beans/ApplicationBean.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.beans;
2 |
3 | import java.io.Serializable;
4 |
5 | import javax.enterprise.context.ApplicationScoped;
6 | import javax.inject.Inject;
7 | import javax.inject.Named;
8 |
9 | @Named
10 | @ApplicationScoped
11 | public class ApplicationBean implements Serializable {
12 |
13 | private static final long serialVersionUID = -8572299300825949098L;
14 |
15 | @Inject
16 | private HelloProducer1 helloProducer1;
17 |
18 | // @Inject
19 | // private HelloProducer2 helloProducer2;
20 |
21 | private int helloCount = 0;
22 |
23 | public String hello() {
24 | helloCount ++;
25 | return "ApplicationBean[helloCount=" + helloCount + "]:" + helloProducer1.hello();
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/beans/GroupedConvBean1.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.beans;
2 |
3 | import java.io.Serializable;
4 |
5 | import javax.inject.Inject;
6 | import javax.inject.Named;
7 |
8 | import org.apache.deltaspike.core.api.scope.GroupedConversationScoped;
9 | import org.apache.deltaspike.core.spi.scope.conversation.GroupedConversationManager;
10 |
11 | @Named
12 | @GroupedConversationScoped
13 | public class GroupedConvBean1 implements Serializable {
14 |
15 | private static final long serialVersionUID = 3051650311158372971L;
16 |
17 | private static int conversationCount = 0;
18 |
19 | private int conversationId;
20 |
21 | @Inject
22 | private HelloProducer1 helloProducer1;
23 |
24 | @Inject
25 | private HelloProducer2 helloProducer2;
26 |
27 | @Inject
28 | private GroupedConversationManager conversationManager;
29 |
30 | private int helloCount = 0;
31 |
32 | public GroupedConvBean1() {
33 | conversationId = conversationCount;
34 | conversationCount ++;
35 | }
36 |
37 | public String hello() {
38 | helloCount ++;
39 | return "GroupedConvBean1[conversationId=" + conversationId + ",helloCount=" + helloCount + "]:" + helloProducer2.hello();
40 | }
41 |
42 | public void closeConversation() {
43 | conversationManager.closeConversationGroup(getClass());
44 | }
45 |
46 | public void closeAllWindowConversations() {
47 | conversationManager.closeConversations();
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/beans/GroupedConvBean2.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.beans;
2 |
3 | import java.io.Serializable;
4 |
5 | import javax.inject.Inject;
6 | import javax.inject.Named;
7 |
8 | import org.apache.deltaspike.core.api.scope.ConversationGroup;
9 | import org.apache.deltaspike.core.api.scope.GroupedConversationScoped;
10 | import org.apache.deltaspike.core.spi.scope.conversation.GroupedConversationManager;
11 |
12 | @Named
13 | @GroupedConversationScoped
14 | @ConversationGroup(MyConversationGroup.class)
15 | public class GroupedConvBean2 implements Serializable {
16 |
17 | private static final long serialVersionUID = -3305275675889306638L;
18 |
19 | private static int conversationCount = 0;
20 |
21 | private int conversationId;
22 |
23 | @Inject
24 | private HelloProducer1 helloProducer1;
25 |
26 | @Inject
27 | private GroupedConversationManager conversationManager;
28 |
29 | private int helloCount = 0;
30 |
31 | // @Inject
32 | // private HelloProducer2 helloProducer2;
33 | //
34 | // @Inject
35 | // private HelloProducer1 helloProducer3;
36 |
37 | public GroupedConvBean2() {
38 | conversationId = conversationCount;
39 | conversationCount ++;
40 | }
41 |
42 | public String hello() {
43 | helloCount ++;
44 | return "GroupedConvBean2[conversationId=" + conversationId + ",helloCount=" + helloCount + "]:" + helloProducer1.hello();
45 | }
46 |
47 | public void closeConversation() {
48 | conversationManager.closeConversationGroup(MyConversationGroup.class);
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/beans/GroupedConvBean3.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.beans;
2 |
3 | import java.io.Serializable;
4 |
5 | import javax.inject.Inject;
6 | import javax.inject.Named;
7 |
8 | import org.apache.deltaspike.core.api.scope.ConversationGroup;
9 | import org.apache.deltaspike.core.api.scope.GroupedConversationScoped;
10 |
11 | @Named
12 | @GroupedConversationScoped
13 | @ConversationGroup(MyConversationGroup.class)
14 | public class GroupedConvBean3 implements Serializable {
15 |
16 | private static final long serialVersionUID = -7175483534416650494L;
17 |
18 | private static int conversationCount = 0;
19 |
20 | private int conversationId;
21 |
22 | @Inject
23 | private HelloProducer1 helloProducer1;
24 |
25 | private int helloCount = 0;
26 |
27 | @Inject
28 | private HelloProducer2 helloProducer2;
29 | //
30 | // @Inject
31 | // private HelloProducer1 helloProducer3;
32 |
33 | public GroupedConvBean3() {
34 | conversationId = conversationCount;
35 | conversationCount ++;
36 | }
37 |
38 | public String hello() {
39 | helloCount ++;
40 | return "GroupedConvBean3[conversationId=" + conversationId + ",helloCount=" + helloCount + "]:" + helloProducer2.hello();
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/beans/HelloProducer1.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.beans;
2 |
3 | import java.io.Serializable;
4 |
5 | import javax.enterprise.context.Dependent;
6 |
7 | @Dependent
8 | public class HelloProducer1 implements Serializable {
9 |
10 | private static final long serialVersionUID = 3869560189111153965L;
11 |
12 | public String hello() {
13 | return "HelloProducer1:hello";
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/beans/HelloProducer2.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.beans;
2 |
3 | import java.io.Serializable;
4 |
5 | import javax.enterprise.context.SessionScoped;
6 |
7 | @SessionScoped
8 | public class HelloProducer2 implements Serializable {
9 |
10 | private static final long serialVersionUID = 1426463110054473736L;
11 |
12 | public String hello() {
13 | return "HelloProducer2:hello";
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/beans/JsfViewBean.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.beans;
2 |
3 | import java.io.Serializable;
4 |
5 | import javax.faces.view.ViewScoped;
6 | import javax.inject.Inject;
7 | import javax.inject.Named;
8 |
9 | @Named
10 | @ViewScoped
11 | public class JsfViewBean implements Serializable {
12 |
13 | private static final long serialVersionUID = -8176648612947203701L;
14 |
15 | private static int idCount = 0;
16 |
17 | private int beanId;
18 |
19 | @Inject
20 | private HelloProducer1 helloProducer1;
21 |
22 | @Inject
23 | private HelloProducer2 helloProducer2;
24 |
25 | private int helloCount = 0;
26 |
27 | public JsfViewBean() {
28 | beanId = idCount;
29 | idCount ++;
30 | }
31 |
32 | public String hello() {
33 | helloCount ++;
34 | return "JsfViewBean[beanId=" + beanId + ",helloCount=" + helloCount + "]:" + helloProducer2.hello();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/beans/ManagedBean.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.beans;
2 |
3 | import java.io.Serializable;
4 |
5 | import javax.inject.Inject;
6 | import javax.inject.Named;
7 |
8 | @Named
9 | public class ManagedBean implements Serializable {
10 |
11 | private static final long serialVersionUID = -3776778289861207553L;
12 |
13 | private static int idCount = 0;
14 |
15 | private int beanId;
16 |
17 | @Inject
18 | private HelloProducer1 helloProducer1;
19 |
20 | @Inject
21 | private HelloProducer2 helloProducer2;
22 |
23 | @Inject
24 | private HelloProducer2 helloProducer3;
25 |
26 | private int helloCount = 0;
27 |
28 | public ManagedBean() {
29 | beanId = idCount;
30 | idCount ++;
31 | }
32 |
33 | public String hello() {
34 | helloCount ++;
35 | return "ManagedBean[beanId=" + beanId + ",helloCount=" + helloCount + "]:" + helloProducer3.hello();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/beans/MyConversationGroup.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.beans;
2 |
3 | public class MyConversationGroup {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/beans/OmniViewBean.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.beans;
2 |
3 | import java.io.Serializable;
4 |
5 | import javax.inject.Inject;
6 | import javax.inject.Named;
7 |
8 | import org.omnifaces.cdi.ViewScoped;
9 |
10 | @Named
11 | @ViewScoped
12 | public class OmniViewBean implements Serializable {
13 |
14 | private static final long serialVersionUID = -8176648612947203701L;
15 |
16 | private static int idCount = 0;
17 |
18 | private int beanId;
19 |
20 | @Inject
21 | private HelloProducer1 helloProducer1;
22 |
23 | // @Inject
24 | // private HelloProducer2 helloProducer2;
25 |
26 | private int helloCount = 0;
27 |
28 | public OmniViewBean() {
29 | beanId = idCount;
30 | idCount ++;
31 | }
32 |
33 | public String hello() {
34 | helloCount ++;
35 | return "OmniViewBean[beanId=" + beanId + ",helloCount=" + helloCount + "]:" + helloProducer1.hello();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/beans/SessionBean.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.beans;
2 |
3 | import java.io.Serializable;
4 |
5 | public class SessionBean implements Serializable {
6 |
7 | private static final long serialVersionUID = 1320916719573569233L;
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/beans/WindowBean.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.beans;
2 |
3 | import java.io.Serializable;
4 |
5 | import javax.inject.Inject;
6 | import javax.inject.Named;
7 |
8 | import org.apache.deltaspike.core.api.scope.WindowScoped;
9 |
10 | @Named
11 | @WindowScoped
12 | public class WindowBean implements Serializable {
13 |
14 | private static final long serialVersionUID = 6608194853271664609L;
15 |
16 | private static int windowCount = 0;
17 |
18 | private int windowId;
19 |
20 | @Inject
21 | private HelloProducer1 helloProducer1;
22 |
23 | private int helloCount = 0;
24 |
25 | // @Inject
26 | // private HelloProducer2 helloProducer2;
27 | //
28 | // @Inject
29 | // private HelloProducer1 helloProducer3;
30 | //
31 | public WindowBean() {
32 | windowId = windowCount;
33 | windowCount ++;
34 | }
35 |
36 | public String hello() {
37 | helloCount ++;
38 | return "WindowBean[windowId=" + windowId + ",helloCount=" + helloCount + "]:" + helloProducer1.hello();
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/em/EntityManagerFactoryProducer.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.em;
2 |
3 | import javax.enterprise.context.ApplicationScoped;
4 | import javax.enterprise.inject.Disposes;
5 | import javax.enterprise.inject.Produces;
6 | import javax.persistence.EntityManagerFactory;
7 | import javax.persistence.Persistence;
8 |
9 | public class EntityManagerFactoryProducer {
10 | @Produces
11 | @ApplicationScoped
12 | public EntityManagerFactory create() {
13 | return Persistence.createEntityManagerFactory("testPU");
14 | }
15 |
16 | public void destroy(@Disposes EntityManagerFactory factory) {
17 | factory.close();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/em/EntityManagerProducer.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.em;
2 |
3 | import javax.enterprise.context.RequestScoped;
4 | import javax.enterprise.inject.Disposes;
5 | import javax.enterprise.inject.Produces;
6 | import javax.inject.Inject;
7 | import javax.persistence.EntityManager;
8 | import javax.persistence.EntityManagerFactory;
9 |
10 | public class EntityManagerProducer {
11 |
12 | @Inject
13 | private EntityManagerFactory emf;
14 |
15 | @Produces
16 | @RequestScoped
17 | public EntityManager create() {
18 | return emf.createEntityManager();
19 | }
20 |
21 | public void close(@Disposes EntityManager em) {
22 | if (em.isOpen()) {
23 | em.close();
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/enums/UserRole.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.enums;
2 |
3 | public enum UserRole {
4 |
5 | ADMIN("A", "userRole.ADMIN"),
6 | USER("U", "userRole.USER");
7 |
8 | public static UserRole getByCode(String code) {
9 | if (code != null) {
10 | for (UserRole en : UserRole.values()) {
11 | if (code.equals(en.getCode())) {
12 | return en;
13 | }
14 | }
15 | }
16 |
17 | return null;
18 | }
19 |
20 | final String code;
21 | final String rbKey;
22 |
23 | UserRole(String code, String rbKey) {
24 | this.code = code;
25 | this.rbKey = rbKey;
26 | }
27 |
28 | public String getCode() {
29 | return code;
30 | }
31 |
32 | public String getRbKey() {
33 | return rbKey;
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/enums/UserRoleConverter.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.enums;
2 |
3 | import javax.persistence.AttributeConverter;
4 | import javax.persistence.Converter;
5 |
6 | @Converter(autoApply = true)
7 | public class UserRoleConverter implements AttributeConverter {
8 | @Override
9 | public String convertToDatabaseColumn(UserRole attribute) {
10 | return attribute != null ? attribute.getCode() : null;
11 | }
12 |
13 | @Override
14 | public UserRole convertToEntityAttribute(String code) {
15 | return UserRole.getByCode(code);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/forms/LoginForm.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.forms;
2 |
3 | import javax.enterprise.inject.Model;
4 |
5 | import org.hibernate.validator.constraints.NotEmpty;
6 |
7 | @Model
8 | public class LoginForm {
9 |
10 | @NotEmpty
11 | private String userName = "admin";
12 |
13 | @NotEmpty
14 | private String password = "admin";
15 |
16 | public String getUserName() {
17 | return userName;
18 | }
19 |
20 | public void setUserName(String userName) {
21 | this.userName = userName;
22 | }
23 |
24 | public String getPassword() {
25 | return password;
26 | }
27 |
28 | public void setPassword(String password) {
29 | this.password = password;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/forms/UserForm.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.forms;
2 |
3 | import java.io.Serializable;
4 |
5 | import javax.enterprise.inject.Model;
6 |
7 | import org.hotswap.agent.example.deltaspike.enums.UserRole;
8 |
9 | @Model
10 | public class UserForm implements Serializable {
11 |
12 | private static final long serialVersionUID = 1243968054551528996L;
13 |
14 | private Long userId;
15 |
16 | private String userName;
17 |
18 | private String firstName;
19 |
20 | private String lastName;
21 |
22 | private UserRole role = UserRole.USER;
23 |
24 | private boolean active;
25 |
26 | private String email;
27 |
28 | public boolean isNew() {
29 | return userId == null;
30 | }
31 |
32 | public Long getUserId() {
33 | return userId;
34 | }
35 |
36 | public void setUserId(Long userId) {
37 | this.userId = userId;
38 | }
39 |
40 | public String getUserName() {
41 | return userName;
42 | }
43 |
44 | public void setUserName(String userName) {
45 | this.userName = userName;
46 | }
47 |
48 | public String getFirstName() {
49 | return firstName;
50 | }
51 |
52 | public void setFirstName(String firstName) {
53 | this.firstName = firstName;
54 | }
55 |
56 | public String getLastName() {
57 | return lastName;
58 | }
59 |
60 | public void setLastName(String lastName) {
61 | this.lastName = lastName;
62 | }
63 |
64 | public UserRole getRole() {
65 | return role;
66 | }
67 |
68 | public void setRole(UserRole role) {
69 | this.role = role;
70 | }
71 |
72 | public boolean isActive() {
73 | return active;
74 | }
75 |
76 | public void setActive(boolean active) {
77 | this.active = active;
78 | }
79 |
80 | public String getEmail() {
81 | return email;
82 | }
83 |
84 | public void setEmail(String email) {
85 | this.email = email;
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/jpa/User.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.jpa;
2 |
3 | import java.io.Serializable;
4 | import java.util.Date;
5 |
6 | import javax.persistence.Column;
7 | import javax.persistence.Entity;
8 | import javax.persistence.GeneratedValue;
9 | import javax.persistence.Id;
10 | import javax.persistence.Table;
11 |
12 | import org.hotswap.agent.example.deltaspike.enums.UserRole;
13 |
14 | @Entity
15 | @Table(name = "USERS")
16 | public class User implements Serializable {
17 |
18 | private static final long serialVersionUID = -1382710855011197405L;
19 |
20 | @Id
21 | @GeneratedValue
22 | @Column(name = "user_id", nullable = false)
23 | private Long userId;
24 | @Column(name = "user_name", nullable = false)
25 | private String userName;
26 | @Column(name = "first_name", nullable = false)
27 | private String firstName;
28 | @Column(name = "last_name", nullable = false)
29 | private String lastName;
30 | @Column(name = "email")
31 | private String email;
32 | @Column(name = "role", nullable = false)
33 | private UserRole role;
34 | @Column(name = "update_date")
35 | private Date updateDate;
36 |
37 | public UserRole getRole() {
38 | return role;
39 | }
40 |
41 | public void setRole(UserRole role) {
42 | this.role = role;
43 | }
44 |
45 | public User() {
46 | }
47 |
48 | public User(Long userId) {
49 | this.userId = userId;
50 | }
51 |
52 | public Long getUserId() {
53 | return userId;
54 | }
55 |
56 | public void setUserId(Long userId) {
57 | this.userId = userId;
58 | }
59 |
60 | public String getUserName() {
61 | return userName;
62 | }
63 |
64 | public void setUserName(String userName) {
65 | this.userName = userName;
66 | }
67 |
68 | public String getFirstName() {
69 | return firstName;
70 | }
71 |
72 | public void setFirstName(String firstName) {
73 | this.firstName = firstName;
74 | }
75 |
76 | public String getLastName() {
77 | return lastName;
78 | }
79 |
80 | public void setLastName(String lastName) {
81 | this.lastName = lastName;
82 | }
83 |
84 | public String getEmail() {
85 | return email;
86 | }
87 |
88 | public void setEmail(String email) {
89 | this.email = email;
90 | }
91 |
92 | public Date getUpdateDate() {
93 | return updateDate;
94 | }
95 |
96 | public void setUpdateDate(Date updateDate) {
97 | this.updateDate = updateDate;
98 | }
99 |
100 | @Override
101 | public int hashCode() {
102 | int hash = 0;
103 | hash += (userId != null ? userId.hashCode() : 0);
104 | return hash;
105 | }
106 |
107 | @Override
108 | public boolean equals(Object object) {
109 | if (!(object instanceof User)) {
110 | return false;
111 | }
112 | User other = (User) object;
113 | if ((this.userId == null && other.userId != null) || (this.userId != null && !this.userId.equals(other.userId))) {
114 | return false;
115 | }
116 | return true;
117 | }
118 |
119 | @Override
120 | public String toString() {
121 | return "org.hotswap.agent.example.deltaspike.jpa.User[userId=" + userId + "]";
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/jpa/UserRepository.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.jpa;
2 |
3 |
4 | import org.apache.deltaspike.data.api.AbstractEntityRepository;
5 | import org.apache.deltaspike.data.api.Repository;
6 |
7 | @Repository
8 | public abstract class UserRepository extends AbstractEntityRepository {
9 |
10 | public abstract User findOptionalByUserName(String userName);
11 |
12 | public abstract User findOptionalByUserId(Long userId);
13 | }
14 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/jsf/AppJsfModuleConfig.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.jsf;
2 |
3 | import javax.enterprise.inject.Specializes;
4 |
5 | import org.apache.deltaspike.jsf.api.config.JsfModuleConfig;
6 | import org.apache.deltaspike.jsf.spi.scope.window.ClientWindowConfig;
7 |
8 | @Specializes
9 | public class AppJsfModuleConfig extends JsfModuleConfig {
10 |
11 | private static final long serialVersionUID = -3382887706461201688L;
12 |
13 | @Override
14 | public ClientWindowConfig.ClientWindowRenderMode getDefaultWindowMode() {
15 | return ClientWindowConfig.ClientWindowRenderMode.NONE;
16 | }
17 | }
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/jsf/Messages.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.jsf;
2 |
3 | import org.apache.deltaspike.core.api.message.MessageBundle;
4 | import org.apache.deltaspike.core.api.message.MessageTemplate;
5 |
6 | @MessageBundle
7 | public interface Messages {
8 |
9 | @MessageTemplate("login.msg.loginOk")
10 | public String loginOk();
11 |
12 | @MessageTemplate("login.msg.loginFailed")
13 | public String loginFailed();
14 |
15 | @MessageTemplate("common.saveOK")
16 | public String saveOK();
17 |
18 | @MessageTemplate("common.saveFailed")
19 | public String saveFailed();
20 |
21 | @MessageTemplate("common.deleteOK")
22 | public String deleteOK();
23 |
24 | @MessageTemplate("common.deleteFailed")
25 | public String deleteFailed();
26 | }
27 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/java/org/hotswap/agent/example/deltaspike/jsf/Pages.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.deltaspike.jsf;
2 |
3 | import org.apache.deltaspike.core.api.config.view.ViewConfig;
4 | import org.apache.deltaspike.jsf.api.config.view.Folder;
5 | import org.apache.deltaspike.jsf.api.config.view.View;
6 | import org.apache.deltaspike.jsf.api.config.view.View.NavigationMode;
7 |
8 | @Folder(name="/")
9 | public interface Pages extends ViewConfig {
10 |
11 | class Index implements ViewConfig {}
12 |
13 | @View(navigation = NavigationMode.REDIRECT)
14 | public interface Appl extends Pages {
15 |
16 | class Beans implements Appl {};
17 | class Users implements Appl {}
18 |
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/resources/META-INF/beans.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/resources/META-INF/persistence.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/resources/hotswap-agent.properties:
--------------------------------------------------------------------------------
1 | # Logger level
2 | # LOGGER=warning
3 | # LOGGER.org.hotswap.agent.plugin.owb=trace
4 | # LOGGER.org.hotswap.agent.plugin.weld=trace
5 | # LOGGER.org.hotswap.agent.plugin.cdi=debug
6 | # reference -Dextra.class.path=...
7 | autoHotswap=true
8 | extraClassPath=${extra.class.path}
9 | webappDir=${webapp.dir}
10 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/resources/messages_en.properties:
--------------------------------------------------------------------------------
1 | app.title=HotswapAgent - Deltaspike TEST
2 | common.save=Save
3 | common.cancel=Cancel
4 | common.areYouSureToDelete=Are you sure to delete?
5 | common.yes=Yes
6 | common.no=No
7 | menu.home=Home
8 | menu.users=Repository Test (Users)
9 | menu.beans=Context Tests
10 | users=Users
11 | users.userName=User name
12 | users.firstName=First name
13 | users.lastName=Last name
14 | users.email=Email
15 | users.role=Role
16 | users.new=New user
17 | users.userId=User ID
18 | users.user=User
19 | userRole.ADMIN=Admin
20 | userRole.USER=User
21 | error.loginPage=To login page
22 | error.refresh=refresh
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/webapp/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Class-Path:
3 |
4 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/webapp/META-INF/context.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
11 |
12 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/webapp/WEB-INF/beans.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
10 |
11 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/webapp/WEB-INF/faces-config.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 | messages
11 | messages
12 |
13 |
14 | en
15 | en
16 |
17 |
18 |
19 |
20 |
21 | org.omnifaces.context.OmniPartialViewContextFactory
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | deltaspike-hibernate-jsf
4 |
5 |
6 | Faces Servlet
7 | javax.faces.webapp.FacesServlet
8 | 1
9 |
10 |
11 |
12 | Faces Servlet
13 | *.jsf
14 |
15 |
16 |
17 |
18 | org.apache.webbeans.servlet.WebBeansConfigurationListener
19 |
20 |
21 |
22 |
27 |
28 |
29 | BeanManager
30 | javax.enterprise.inject.spi.BeanManager
31 |
32 |
33 |
34 | org.hotswap.agent.example.deltaspike.ContextListener
35 |
36 |
37 |
38 | javax.faces.PROJECT_STAGE
39 | Development
40 |
41 |
42 |
43 | javax.faces.FACELETS_REFRESH_PERIOD
44 | 0
45 |
46 |
47 |
48 | javax.faces.DEFAULT_SUFFIX
49 | .xhtml
50 |
51 |
52 |
53 | primefaces.THEME
54 | blitzer
55 |
56 |
57 |
58 | primefaces.FONT_AWESOME
59 | true
60 |
61 |
62 |
63 | javax.faces.FACELETS_SKIP_COMMENTS
64 | true
65 |
66 |
67 |
68 | javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE
69 | true
70 |
71 |
72 |
73 | woff2
74 | application/x-font-woff2
75 |
76 |
77 |
78 | 10
79 |
80 |
81 |
82 | 500
83 | /errorpages/error.jsf
84 |
85 |
86 |
87 | 404
88 | /errorpages/not-found.jsf
89 |
90 |
91 |
92 | javax.faces.application.ViewExpiredException
93 | /errorpages/view-expired.jsf
94 |
95 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/webapp/appl/beans.xhtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
13 |
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 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/webapp/errorpages/error.xhtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 | #{messages['pageTitle.error']}
13 |
14 |
15 |
16 |
17 |
18 | Chyba
19 |
20 |
21 |
22 | #{messages['error.loginPage']}
23 |
24 | #{messages['error.refresh']}
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/webapp/errorpages/lowPriviliges.xhtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | #{messages['error.accessDenied']}
18 |
19 | Login page
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/webapp/errorpages/notFound.xhtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | 404
19 |
20 | Login page
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/webapp/errorpages/viewExpired.xhtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | Sezení ukončeno.
18 |
19 | Login page
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/webapp/include/header.xhtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 | #{messages['app.title']}#{not empty pageTitle ? ' - '.concat(pageTitle) : ''}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/webapp/include/menu.xhtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
13 |
14 |
15 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/webapp/index.xhtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/deltaspike-hibernate-jsf/src/main/webapp/resources/css/default.css:
--------------------------------------------------------------------------------
1 | .ui-widget, .ui-widget .ui-widget {
2 | font-size: 90%;
3 | }
4 |
5 | .login-panel {
6 | position: absolute;
7 | top: 0;
8 | bottom: 0;
9 | left: 0;
10 | right: 0;
11 | display: flex;
12 | justify-content: space-around;
13 | align-items: center;
14 | flex-wrap: wrap;
15 | }
--------------------------------------------------------------------------------
/gae/.gitignore:
--------------------------------------------------------------------------------
1 | .classpath
2 | .idea
3 | .project
4 | .settings/
5 | target/
6 | *.iml
7 |
--------------------------------------------------------------------------------
/gae/.idea/codeStyleSettings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
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 |
--------------------------------------------------------------------------------
/gae/README.md:
--------------------------------------------------------------------------------
1 | [Issue 12426 - googleappengine - Passing JVM options to devserver - Google App Engine - Google Project Hosting](https://code.google.com/p/googleappengine/issues/detail?id=12426)
2 |
3 | [java.lang.NoClassDefFoundError: org/hotswap/agent/config/PluginManager - GAE devserver · Issue #99 · HotswapProjects/HotswapAgent](https://github.com/HotswapProjects/HotswapAgent/issues/99)
4 |
5 | How to test multi-module app?
6 |
7 | ```
8 | git clone https://github.com/HotswapProjects/HotswapAgentExamples
9 | cd HotswapAgentExamples/gae
10 | mvn
11 | cd ear
12 | mvn
13 | ```
14 |
15 | How to test normal (single/default module) app?
16 | ```
17 | git clone https://github.com/HotswapProjects/HotswapAgentExamples
18 | cd HotswapAgentExamples/gae
19 | mvn
20 | cd gae-default
21 | mvn
22 | ```
23 |
--------------------------------------------------------------------------------
/gae/ear/pom.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 | com.google.developers
6 | gae-parent
7 | 0.0.1-SNAPSHOT
8 |
9 |
10 | 4.0.0
11 |
12 | gae-ear
13 |
14 | ear
15 |
16 | gae-ear
17 |
18 | http://developers.google.com/
19 |
20 |
21 |
22 | 3.1.0
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | org.apache.maven.plugins
31 | maven-ear-plugin
32 | 2.10
33 |
34 | 5
35 | lib
36 | war
37 |
38 | true
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | maven-help-plugin
47 |
48 |
49 | org.codehaus.mojo
50 | versions-maven-plugin
51 |
52 |
53 | com.google.appengine
54 | appengine-maven-plugin
55 |
56 |
57 |
58 |
59 |
60 |
63 |
64 |
65 | local
66 |
67 | true
68 |
69 |
70 | appengine:devserver
71 |
72 |
73 |
74 | dev
75 |
76 | clean appengine:update
77 |
78 |
79 |
80 | beta
81 |
82 | clean appengine:update
83 |
84 |
85 |
86 |
87 |
88 |
89 | com.google.developers
90 | gae-default
91 | 0.0.1-SNAPSHOT
92 | war
93 |
94 |
95 | com.google.developers
96 | gae-backend
97 | 0.0.1-SNAPSHOT
98 | war
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/gae/ear/src/main/application/META-INF/appengine-application.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ${appengine.app.id}
6 |
7 |
8 |
--------------------------------------------------------------------------------
/gae/ear/src/main/application/META-INF/application.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | GAE multi-module sample
6 | GAE multi-module sample
7 |
8 |
9 | gae-default-0.0.1-SNAPSHOT.war
10 | default
11 |
12 |
13 |
14 |
15 | gae-backend-0.0.1-SNAPSHOT.war
16 | backend
17 |
18 |
19 | lib
20 |
21 |
--------------------------------------------------------------------------------
/gae/gae-backend/src/main/java/com/google/developers/BackendServlet.java:
--------------------------------------------------------------------------------
1 | package com.google.developers;
2 |
3 | import com.google.inject.Singleton;
4 |
5 | import javax.servlet.ServletException;
6 | import javax.servlet.http.HttpServlet;
7 | import javax.servlet.http.HttpServletRequest;
8 | import javax.servlet.http.HttpServletResponse;
9 | import java.io.IOException;
10 |
11 | /**
12 | * this is a batch process entry point
13 | *
14 | * Created by renfeng on 7/5/15.
15 | */
16 | @Singleton
17 | public class BackendServlet extends HttpServlet {
18 |
19 | @Override
20 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
21 | /*
22 | * TODO long task
23 | */
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/gae/gae-backend/src/main/java/com/google/developers/BackendServletModule.java:
--------------------------------------------------------------------------------
1 | package com.google.developers;
2 |
3 | import com.google.inject.servlet.ServletModule;
4 |
5 | public class BackendServletModule extends ServletModule {
6 |
7 | @Override
8 | protected void configureServlets() {
9 | serve("/cron/long-task").with(BackendServlet.class);
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/gae/gae-backend/src/main/java/com/google/developers/BackendStartupListener.java:
--------------------------------------------------------------------------------
1 | package com.google.developers;
2 |
3 | import com.google.inject.Guice;
4 | import com.google.inject.Injector;
5 | import com.google.inject.Stage;
6 | import com.google.inject.servlet.GuiceServletContextListener;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | import javax.servlet.ServletContextEvent;
11 |
12 | public class BackendStartupListener extends GuiceServletContextListener {
13 |
14 | private static final Logger logger = LoggerFactory
15 | .getLogger(BackendStartupListener.class);
16 |
17 | private Injector injector;
18 |
19 | @Override
20 | public void contextInitialized(ServletContextEvent sce) {
21 |
22 | /*
23 | * TODO switch to production
24 | */
25 | injector = Guice.createInjector(Stage.DEVELOPMENT,
26 | new DevelopersSharedModule(),
27 | new DevelopersSharedServletModule(),
28 | new BackendServletModule());
29 | logger.info("created injector");
30 |
31 | super.contextInitialized(sce);
32 |
33 | return;
34 | }
35 |
36 | @Override
37 | protected Injector getInjector() {
38 | return injector;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/gae/gae-backend/src/main/webapp/WEB-INF/appengine-web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | ${appengine.app.id}
8 |
9 |
10 |
11 | ${appengine.module.backend}
12 |
13 | ${appengine.app.version}
14 |
15 |
16 | true
17 |
18 |
19 | B2
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | ${appengine.module.instances}
29 |
30 | 1m
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/gae/gae-backend/src/main/webapp/WEB-INF/logging.properties:
--------------------------------------------------------------------------------
1 | # A default java.util.logging configuration.
2 | # (All App Engine logging is through java.util.logging by default).
3 | #
4 | # To use this configuration, copy it into your application's WEB-INF
5 | # folder and add the following to your appengine-web.xml:
6 | #
7 | #
8 | #
9 | #
10 | #
11 |
12 | # Set the default logging level for all loggers to WARNING
13 | .level = WARNING
14 |
15 | # Set up logging of HTTP requests and responses (uncomment "level" to show)
16 | #com.google.api.client.http.level = CONFIG
17 | com.google.api.client.http.level = FINE
18 |
19 | # TODO maven filtering
20 | # http://docs.oracle.com/javase/7/docs/api/java/util/logging/Level.html
21 | com.google..developers.level = ALL
22 |
23 | # http://www.slf4j.org/api/org/slf4j/bridge/SLF4JBridgeHandler.html
24 | # FINEST -> TRACE
25 | # FINER -> DEBUG
26 | # FINE -> DEBUG
27 | # INFO -> INFO
28 | # WARNING -> WARN
29 | # SEVERE -> ERROR
30 |
--------------------------------------------------------------------------------
/gae/gae-backend/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | ${project.name} (${buildNumber})
8 |
9 |
10 |
11 |
12 | guiceFilter
13 | ${guice.filter}
14 |
15 |
16 | guiceFilter
17 | /*
18 |
19 |
20 |
21 | com.google.developers.BackendStartupListener
22 |
23 |
24 |
25 | java.lang.Exception
26 | /api/5xx/
27 |
28 |
29 |
30 |
31 |
32 |
33 | everything
34 | /*
35 |
36 |
37 | CONFIDENTIAL
38 |
39 |
40 |
41 |
42 |
43 | admin
44 |
45 | /admin/*
46 |
47 |
48 | /cron/*
49 |
50 |
51 | /_ah/queue/*
52 |
53 |
54 | /_ah/mail/*
55 |
56 |
57 | /_ah/bounce
58 |
59 |
60 | /appstats/*
61 |
62 |
63 |
64 | admin
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/gae/gae-backend/src/main/webapp/api/5xx/index.jsp:
--------------------------------------------------------------------------------
1 | <%@ page language="java" trimDirectiveWhitespaces="true"
2 | contentType="application/json; charset=UTF-8" pageEncoding="UTF-8"
3 | isErrorPage="true"
4 | import="com.google.inject.Injector,com.google.api.client.json.JsonFactory,com.google.api.client.json.JsonGenerator"%>
5 | <%
6 | Injector injector = (Injector) application
7 | .getAttribute("com.google.inject.Injector");
8 | String m = pageContext.getException().getLocalizedMessage();
9 | JsonFactory jsonFactory = injector.getInstance(JsonFactory.class);
10 | JsonGenerator generator = jsonFactory.createJsonGenerator(out);
11 | generator.writeStartObject();
12 | generator.writeFieldName("error");
13 | generator.writeString(m);
14 | generator.writeEndObject();
15 | generator.flush();
16 | %>
--------------------------------------------------------------------------------
/gae/gae-backend/src/main/webapp/index.html:
--------------------------------------------------------------------------------
1 | hello
--------------------------------------------------------------------------------
/gae/gae-default/pom.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 | gae-parent
6 | com.google.developers
7 | 0.0.1-SNAPSHOT
8 |
9 |
10 | 4.0.0
11 |
12 | gae-default
13 |
14 | war
15 |
16 | gae-default
17 |
18 | default module for gae
19 |
20 | https://developers.google.com/
21 |
22 |
23 | 2.2.1
24 |
25 |
26 |
27 |
28 | +FrankR
29 | Frank R.
30 | renfeng.cn@gmail.com
31 | https://plus.google.com/+FrankR
32 | GDG Suzhou
33 | http://developers.dushu.hu
34 | +8
35 |
36 | Organizer
37 |
38 |
39 |
40 |
41 |
42 | scm:git:https://github.com/renfeng/HotswapAgentExamples/commit/${buildNumber}
43 |
44 |
45 |
46 | GDG Suzhou
47 | http://developers.dushu.hu/
48 |
49 |
50 |
51 | ${project.build.directory}/${project.build.finalName}/WEB-INF/classes
52 | gae-default
53 |
54 |
55 |
56 |
57 |
58 |
59 | maven-help-plugin
60 |
61 |
62 | org.codehaus.mojo
63 | versions-maven-plugin
64 |
65 |
66 | org.codehaus.mojo
67 | buildnumber-maven-plugin
68 |
69 |
70 | maven-war-plugin
71 |
72 |
73 | com.google.appengine
74 | appengine-maven-plugin
75 |
76 |
77 |
78 |
79 |
80 |
81 |
84 |
85 |
86 | local
87 |
88 | true
89 |
90 |
91 | appengine:devserver
92 |
93 |
94 |
95 | dev
96 |
97 | clean install appengine:update
98 |
99 |
100 |
101 | beta
102 |
103 | clean install appengine:update
104 |
105 |
106 |
107 |
108 |
109 |
110 | com.google.developers
111 | gae-shared
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/gae/gae-default/src/main/java/com/google/developers/DefaultServletModule.java:
--------------------------------------------------------------------------------
1 | package com.google.developers;
2 |
3 | import com.google.api.server.spi.SystemServiceServlet;
4 | import com.google.inject.Singleton;
5 | import com.google.inject.servlet.ServletModule;
6 | import com.google.training.helloworld.HelloWorldEndpoints;
7 |
8 | import java.util.HashMap;
9 |
10 | public class DefaultServletModule extends ServletModule implements Path {
11 |
12 | @Override
13 | protected void configureServlets() {
14 |
15 | /*
16 | * /api/401/;jsessionid=37fycpy88nx7
17 | */
18 | serve("/api/401/*").with(UnauthorizedServlet.class);
19 |
20 | /*
21 | * A servlet is a singleton, and is allowed to be registered only once.
22 | */
23 |
24 | {
25 | HashMap params = new HashMap<>();
26 |
27 | /*
28 | * comma delimited fqn of classes
29 | */
30 | params.put("services", HelloWorldEndpoints.class.getCanonicalName());
31 |
32 | serve("/_ah/spi/*").with(SystemServiceServlet.class, params);
33 | bind(SystemServiceServlet.class).in(Singleton.class);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/gae/gae-default/src/main/java/com/google/developers/DefaultStartupListener.java:
--------------------------------------------------------------------------------
1 | package com.google.developers;
2 |
3 | import com.google.inject.Guice;
4 | import com.google.inject.Injector;
5 | import com.google.inject.Stage;
6 | import com.google.inject.servlet.GuiceServletContextListener;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | import javax.servlet.ServletContextEvent;
11 |
12 | /**
13 | * loader for the web application
14 | *
15 | * @author renfeng
16 | */
17 | public class DefaultStartupListener extends GuiceServletContextListener {
18 |
19 | private static final Logger logger = LoggerFactory
20 | .getLogger(DefaultStartupListener.class);
21 |
22 | /*
23 | * removed static keyword
24 | */
25 | private Injector injector;
26 |
27 | /*
28 | * XXX for deferred task - which i would gave up because of lack of logging
29 | * output in eclipse junit, and unreadable payload on appengine.google.com
30 | */
31 |
32 | @Override
33 | public void contextInitialized(ServletContextEvent sce) {
34 |
35 | /*
36 | * TODO switch to production
37 | */
38 | logger.info("created injector");
39 | injector = Guice.createInjector(Stage.DEVELOPMENT,
40 | new DevelopersSharedModule(),
41 | new DevelopersSharedServletModule(),
42 | new DefaultServletModule());
43 |
44 | super.contextInitialized(sce);
45 | }
46 |
47 | @Override
48 | protected Injector getInjector() {
49 | return injector;
50 | }
51 |
52 | }
--------------------------------------------------------------------------------
/gae/gae-default/src/main/java/com/google/developers/Path.java:
--------------------------------------------------------------------------------
1 | package com.google.developers;
2 |
3 | public interface Path {
4 |
5 | String EVENTS_API_URL = "/api/events/";
6 |
7 | String CHECK_IN_PAGE_URL = "/authenticated/check-in/";
8 | String TICKET_PAGE_URL = "/authenticated/ticket/";
9 | String CAMPAIGN_PAGE_URL = "/authenticated/campaign/";
10 | String EVENT_BRITE_PAGE_URL = "/authenticated/eventbrite/";
11 |
12 | String OAUTH2ENTRY_PAGE_URL = "/authenticated/oauth2entry";
13 | String OAUTH2CALLBACK_PAGE_URL = "/authenticated/oauth2callback";
14 | String OAUTH2REVOKE_PAGE_URL = "/authenticated/oauth2revoke";
15 | }
16 |
--------------------------------------------------------------------------------
/gae/gae-default/src/main/java/com/google/developers/UnauthorizedServlet.java:
--------------------------------------------------------------------------------
1 | package com.google.developers;
2 |
3 | import com.google.api.client.json.JsonFactory;
4 | import com.google.api.client.json.JsonGenerator;
5 | import com.google.inject.Inject;
6 | import com.google.inject.Singleton;
7 |
8 | import javax.servlet.ServletException;
9 | import javax.servlet.http.HttpServlet;
10 | import javax.servlet.http.HttpServletRequest;
11 | import javax.servlet.http.HttpServletResponse;
12 | import java.io.IOException;
13 |
14 | @Singleton
15 | public class UnauthorizedServlet extends HttpServlet {
16 |
17 | private final JsonFactory jsonFactory;
18 |
19 | @Inject
20 | public UnauthorizedServlet(JsonFactory jsonFactory) {
21 | this.jsonFactory = jsonFactory;
22 | }
23 |
24 | protected void unauthorized(HttpServletRequest req, HttpServletResponse resp)
25 | throws IOException {
26 |
27 | String userAgent = req.getHeader("User-Agent");
28 |
29 | resp.setHeader("Content-Type", "text/javascript");
30 | resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
31 |
32 | JsonGenerator generator = jsonFactory.createJsonGenerator(resp.getWriter());
33 | generator.writeStartObject();
34 | generator.writeFieldName("error");
35 | generator.writeString("Login required.");
36 | generator.writeFieldName("q");
37 | generator.writeString(req.getQueryString());
38 | generator.writeFieldName("agent");
39 | generator.writeString(userAgent);
40 | generator.writeEndObject();
41 | generator.flush();
42 | }
43 |
44 | @Override
45 | protected void doGet(HttpServletRequest req, HttpServletResponse resp)
46 | throws ServletException, IOException {
47 | unauthorized(req, resp);
48 | }
49 |
50 | @Override
51 | protected void doPost(HttpServletRequest req, HttpServletResponse resp)
52 | throws ServletException, IOException {
53 | unauthorized(req, resp);
54 | }
55 | }
--------------------------------------------------------------------------------
/gae/gae-default/src/main/java/com/google/training/helloworld/Constants.java:
--------------------------------------------------------------------------------
1 | package com.google.training.helloworld;
2 |
3 | import com.google.api.server.spi.Constant;
4 |
5 | /**
6 | * Contains the client IDs and scopes for allowed clients consuming your API.
7 | */
8 | public class Constants {
9 | public static final String WEB_CLIENT_ID = "replace this with your web client ID";
10 | public static final String ANDROID_CLIENT_ID = "replace this with your Android client ID";
11 | public static final String IOS_CLIENT_ID = "replace this with your iOS client ID";
12 | public static final String ANDROID_AUDIENCE = WEB_CLIENT_ID;
13 | public static final String API_EXPLORER_CLIENT_ID = Constant.API_EXPLORER_CLIENT_ID;
14 | public static final String EMAIL_SCOPE = "https://www.googleapis.com/auth/userinfo.email";
15 | }
16 |
--------------------------------------------------------------------------------
/gae/gae-default/src/main/java/com/google/training/helloworld/HelloClass.java:
--------------------------------------------------------------------------------
1 | package com.google.training.helloworld;
2 |
3 | public class HelloClass {
4 | public String message = "Hello World";
5 |
6 | public HelloClass () {
7 | }
8 |
9 | public HelloClass (String name) {
10 | this.message = "Hello " + name + "!";
11 | }
12 |
13 | public String getMessage() {
14 | return message;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/gae/gae-default/src/main/java/com/google/training/helloworld/HelloWorldEndpoints.java:
--------------------------------------------------------------------------------
1 | package com.google.training.helloworld;
2 |
3 | import com.google.api.server.spi.config.Api;
4 | import com.google.api.server.spi.config.ApiMethod;
5 | import com.google.api.server.spi.config.ApiMethod.HttpMethod;
6 | import com.google.api.server.spi.config.Named;
7 |
8 | /**
9 | * Defines endpoint functions APIs.
10 | */
11 | @Api(name = "helloworldendpoints", version = "v1",
12 | scopes = {Constants.EMAIL_SCOPE},
13 | clientIds = {Constants.WEB_CLIENT_ID, Constants.API_EXPLORER_CLIENT_ID},
14 | description = "API for hello world endpoints.")
15 | public class HelloWorldEndpoints {
16 |
17 | // Declare this method as a method available externally through Endpoints
18 | @ApiMethod(name = "sayHello", path = "sayHello",
19 | httpMethod = HttpMethod.GET)
20 | public HelloClass sayHello() {
21 | return new HelloClass();
22 | }
23 |
24 | // Declare this method as a method available externally through Endpoints
25 | @ApiMethod(name = "sayHelloByName", path = "sayHelloByName",
26 | httpMethod = HttpMethod.GET)
27 | public HelloClass sayHelloByName(@Named("name") String name) {
28 | return new HelloClass(name);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/gae/gae-default/src/main/webapp/WEB-INF/appengine-web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | ${appengine.app.id}
8 |
9 |
10 |
11 |
12 | ${appengine.app.version}
13 |
14 |
15 | true
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
29 | true
30 |
31 |
32 |
33 |
34 |
35 | channel_presence
36 |
37 | mail
38 | mail_bounce
39 |
40 | xmpp_message
41 | xmpp_presence
42 | xmpp_subscribe
43 | xmpp_error
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/gae/gae-default/src/main/webapp/WEB-INF/cron.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
13 |
14 |
15 | /cron/long-task
16 |
17 |
21 |
22 | every 3 hours
23 |
24 |
25 |
28 | ${appengine.module.backend}
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/gae/gae-default/src/main/webapp/WEB-INF/logging.properties:
--------------------------------------------------------------------------------
1 | # A default java.util.logging configuration.
2 | # (All App Engine logging is through java.util.logging by default).
3 | #
4 | # To use this configuration, copy it into your application's WEB-INF
5 | # folder and add the following to your appengine-web.xml:
6 | #
7 | #
8 | #
9 | #
10 | #
11 |
12 | # Set the default logging level for all loggers to WARNING
13 | .level = WARNING
14 |
15 | # Set up logging of HTTP requests and responses (uncomment "level" to show)
16 | #com.google.api.client.http.level = CONFIG
17 | com.google.api.client.http.level = FINE
18 |
19 | # TODO maven filtering
20 | # http://docs.oracle.com/javase/7/docs/api/java/util/logging/Level.html
21 | com.google.developers.level = ALL
22 |
23 | # http://www.slf4j.org/api/org/slf4j/bridge/SLF4JBridgeHandler.html
24 | # FINEST -> TRACE
25 | # FINER -> DEBUG
26 | # FINE -> DEBUG
27 | # INFO -> INFO
28 | # WARNING -> WARN
29 | # SEVERE -> ERROR
30 |
--------------------------------------------------------------------------------
/gae/gae-default/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | ${project.name} (${buildNumber})
8 |
9 |
10 | appengine.app.id
11 | ${appengine.app.id}
12 |
13 |
14 |
15 | guiceFilter
16 | com.google.inject.servlet.GuiceFilter
17 |
18 |
19 | guiceFilter
20 | /*
21 |
22 |
23 |
24 |
25 |
26 |
27 | com.google.developers.DefaultStartupListener
28 |
29 |
30 |
31 | java.lang.Exception
32 | /api/5xx/
33 |
34 |
35 |
36 |
37 |
48 |
49 |
50 |
51 | admin
52 |
53 | /admin/*
54 |
55 |
56 | /cron/*
57 |
58 |
59 | /task/*
60 |
61 |
62 | /_ah/mail/*
63 |
64 |
65 | /_ah/bounce
66 |
67 |
68 |
69 | admin
70 |
71 |
72 |
73 |
74 |
75 | authenticated
76 | /authenticated/*
77 |
78 |
84 |
85 | *
86 |
87 |
88 |
89 |
90 | gdg-index.html
91 | index.html
92 | index.jsp
93 |
94 |
95 |
--------------------------------------------------------------------------------
/gae/gae-default/src/main/webapp/api/5xx/index.jsp:
--------------------------------------------------------------------------------
1 | <%@ page language="java" trimDirectiveWhitespaces="true"
2 | contentType="application/json; charset=UTF-8" pageEncoding="UTF-8"
3 | isErrorPage="true"
4 | import="com.google.inject.Injector,com.google.api.client.json.JsonFactory,com.google.api.client.json.JsonGenerator"%>
5 | <%
6 | Injector injector = (Injector) application
7 | .getAttribute("com.google.inject.Injector");
8 | String m = pageContext.getException().getLocalizedMessage();
9 | JsonFactory jsonFactory = injector.getInstance(JsonFactory.class);
10 | JsonGenerator generator = jsonFactory.createJsonGenerator(out);
11 | generator.writeStartObject();
12 | generator.writeFieldName("error");
13 | generator.writeString(m);
14 | generator.writeEndObject();
15 | generator.flush();
16 | %>
--------------------------------------------------------------------------------
/gae/shared/src/main/java/com/google/developers/DevelopersSharedFilter.java:
--------------------------------------------------------------------------------
1 | package com.google.developers;
2 |
3 | import com.google.appengine.api.modules.ModulesService;
4 | import com.google.appengine.api.modules.ModulesServiceFactory;
5 | import com.google.inject.servlet.GuiceFilter;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import javax.servlet.FilterChain;
10 | import javax.servlet.ServletException;
11 | import javax.servlet.ServletRequest;
12 | import javax.servlet.ServletResponse;
13 | import java.io.IOException;
14 |
15 | public class DevelopersSharedFilter extends GuiceFilter {
16 |
17 | // private static final Logger logger = LoggerFactory
18 | // .getLogger(DevelopersSharedFilter.class);
19 |
20 | @Override
21 | public void doFilter(ServletRequest servletRequest,
22 | ServletResponse servletResponse, FilterChain filterChain)
23 | throws IOException, ServletException {
24 |
25 | ModulesService modulesApi = ModulesServiceFactory.getModulesService();
26 | String instanceHostname = modulesApi.getCurrentInstanceId() + "."
27 | + modulesApi.getCurrentVersion() + "."
28 | + modulesApi.getCurrentModule();
29 | Logger logger = LoggerFactory.getLogger(instanceHostname);
30 | logger.info(logger.getName());
31 |
32 | logger.info("begin guice filter");
33 | super.doFilter(servletRequest, servletResponse, filterChain);
34 | logger.info("end guice filter");
35 |
36 | return;
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/gae/shared/src/main/java/com/google/developers/DevelopersSharedModule.java:
--------------------------------------------------------------------------------
1 | package com.google.developers;
2 |
3 | import com.google.api.client.extensions.appengine.datastore.AppEngineDataStoreFactory;
4 | import com.google.api.client.http.HttpTransport;
5 | import com.google.api.client.http.javanet.NetHttpTransport;
6 | import com.google.api.client.json.JsonFactory;
7 | import com.google.api.client.json.jackson2.JacksonFactory;
8 | import com.google.api.client.util.store.DataStoreFactory;
9 | import com.google.inject.Binder;
10 | import com.google.inject.Module;
11 | import com.google.inject.Singleton;
12 |
13 | import java.text.DateFormat;
14 | import java.text.SimpleDateFormat;
15 | import java.util.ResourceBundle;
16 |
17 | public class DevelopersSharedModule implements Module {
18 |
19 | public static final String REFRESH_TOKEN = getMessage("refreshToken");
20 | public static final String CLIENT_ID = getMessage("clientId");
21 | public static final String CLIENT_SECRET = getMessage("clientSecret");
22 |
23 | @Override
24 | public void configure(Binder binder) {
25 |
26 | // binder.bind(HttpTransport.class).toInstance(new UrlFetchTransport());
27 | binder.bind(HttpTransport.class).toInstance(new NetHttpTransport());
28 |
29 | /*
30 | * TODO HH?
31 | */
32 | binder.bind(DateFormat.class).toInstance(
33 | new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'Z'"));
34 |
35 | binder.bind(JsonFactory.class).toInstance(
36 | JacksonFactory.getDefaultInstance());
37 |
38 | /*
39 | * Global instance of the {@link DataStoreFactory}. The best practice is
40 | * to make it a single globally shared instance across your application.
41 | */
42 | binder.bind(DataStoreFactory.class).toInstance(
43 | AppEngineDataStoreFactory.getDefaultInstance());
44 | binder.bind(AppEngineDataStoreFactory.class).in(Singleton.class);
45 | }
46 |
47 | public static String getMessage(String key) {
48 | /*
49 | * http://docs.oracle.com/javase/tutorial/i18n/intro/steps.html
50 | */
51 | ResourceBundle bundle = ResourceBundle.getBundle("message");
52 | return bundle.getString(key);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/gae/shared/src/main/java/com/google/developers/DevelopersSharedServletModule.java:
--------------------------------------------------------------------------------
1 | package com.google.developers;
2 |
3 | import com.google.inject.servlet.ServletModule;
4 |
5 | public class DevelopersSharedServletModule extends ServletModule {
6 |
7 | @Override
8 | protected void configureServlets() {
9 |
10 | /*
11 | * TODO /_ah/stop (not documented?)
12 | */
13 | serve("/_ah/start").with(ModuleStartServlet.class);
14 |
15 | // serve("/appstats/*").with(AppstatsServlet.class);
16 | // bind(AppstatsServlet.class).in(Singleton.class);
17 |
18 | /*
19 | * url handlers in non-default module require a workaround
20 | * https://code.google.com/p/googleappengine/issues/detail?id=9859
21 | */
22 |
23 | // filter("/*").through(AppstatsFilter.class);
24 | // filter("/*").through(ObjectifyFilter.class);
25 | // bind(ObjectifyFilter.class).in(Singleton.class);
26 |
27 | return;
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/gae/shared/src/main/java/com/google/developers/ModuleStartServlet.java:
--------------------------------------------------------------------------------
1 | package com.google.developers;
2 |
3 | import com.google.appengine.api.LifecycleManager;
4 | import com.google.inject.Inject;
5 | import com.google.inject.Singleton;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import javax.servlet.ServletException;
10 | import javax.servlet.http.HttpServlet;
11 | import javax.servlet.http.HttpServletRequest;
12 | import javax.servlet.http.HttpServletResponse;
13 | import java.io.IOException;
14 |
15 | @Singleton
16 | public class ModuleStartServlet extends HttpServlet implements
17 | LifecycleManager.ShutdownHook {
18 |
19 | private static final Logger logger = LoggerFactory
20 | .getLogger(ModuleStartServlet.class);
21 |
22 | @Inject
23 | public ModuleStartServlet() {
24 | }
25 |
26 | @Override
27 | protected void doGet(HttpServletRequest req, HttpServletResponse resp)
28 | throws ServletException, IOException {
29 |
30 | logger.info("module start");
31 | LifecycleManager.getInstance().setShutdownHook(this);
32 | // ModulesService modulesApi =
33 | // ModulesServiceFactory.getModulesService();
34 | // if ("0".equals(modulesApi.getCurrentInstanceId())) {
35 | //
36 | // logger.info("module start");
37 | // LifecycleManager.getInstance().setShutdownHook(this);
38 | //
39 | // }
40 |
41 | return;
42 | }
43 |
44 | @Override
45 | public void shutdown() {
46 |
47 | logger.info("module shutdown");
48 | // LifecycleManager.getInstance().interruptAllRequests();
49 |
50 | return;
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/gae/shared/src/main/java/com/google/developers/PropertiesContant.java:
--------------------------------------------------------------------------------
1 | package com.google.developers;
2 |
3 | /**
4 | * Created by renfeng on 7/20/15.
5 | */
6 | public interface PropertiesContant {
7 |
8 | String KEY_VALUE_DELIMITER = "=";
9 | String COMMENT_LINE_START = "#";
10 | }
11 |
--------------------------------------------------------------------------------
/hotswap-agent-examples-servlet-parent/README.md:
--------------------------------------------------------------------------------
1 | Setup of application servers
2 | ============================
3 |
4 | ### Jetty9
5 |
6 |
7 | ### JBoss7
8 |
9 |
10 | ### Tomcat7
11 |
--------------------------------------------------------------------------------
/jersey1/README.md:
--------------------------------------------------------------------------------
1 | Run this sample with:
2 | > 'mvn clean package jetty:run -Pjetty9-run'
3 |
4 | Then open:
5 | > http://localhost:8080/rest/jersey1/hello
--------------------------------------------------------------------------------
/jersey1/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | hotswap-agent-examples-aggregator
7 | org.hotswapagent
8 | 1.4.2-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | jersey1
13 |
14 |
15 |
16 | com.sun.jersey
17 | jersey-server
18 | 1.18.3
19 |
20 |
21 | com.sun.jersey
22 | jersey-servlet
23 | 1.18.3
24 |
25 |
26 | org.eclipse.jetty
27 | jetty-server
28 | 9.4.17.v20190418
29 | provided
30 |
31 |
32 |
33 |
34 |
35 | jetty9-run
36 |
37 |
38 |
39 | org.eclipse.jetty
40 | jetty-maven-plugin
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/jersey1/src/main/java/org/hotswap/agent/exemple/jersey/Jersey1Resource.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.exemple.jersey;
2 |
3 | import javax.ws.rs.GET;
4 | import javax.ws.rs.Path;
5 |
6 | /**
7 | * Jersey resource.
8 | */
9 | @Path("/jersey1")
10 | public class Jersey1Resource {
11 |
12 | /**
13 | * Access this resource throw an HTTP request on /rest/jersey1/hello URI.
14 | *
15 | * @return 'Hello from Jersey1!' string
16 | */
17 | @GET
18 | @Path("/hello")
19 | public String hello() {
20 | return "Hello from Jersey 1!";
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/jersey1/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | jersey
6 | com.sun.jersey.spi.container.servlet.ServletContainer
7 |
8 | com.sun.jersey.config.property.packages
9 | org.hotswap.agent.exemple.jersey
10 |
11 |
12 |
13 | jersey
14 | /rest/*
15 |
16 |
--------------------------------------------------------------------------------
/jersey2-jetty-hk2/README.md:
--------------------------------------------------------------------------------
1 | run main method in Jersey2App
2 |
3 | Then open:
4 | > http://localhost:8080/hello
5 |
--------------------------------------------------------------------------------
/jersey2-jetty-hk2/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | hotswap-agent-examples-aggregator
7 | org.hotswapagent
8 | 1.4.2-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | jersey2-jetty-hk2
13 |
14 |
15 |
16 | maven2-repository.java.net
17 | Java.net Repository for Maven
18 | https://maven.java.net/content/groups/public/
19 | default
20 |
21 |
22 |
23 |
24 |
25 |
26 | javax.servlet
27 | javax.servlet-api
28 | 3.1.0
29 |
30 |
31 |
32 | org.glassfish.jersey.core
33 | jersey-server
34 | 2.25
35 |
36 |
37 |
38 | org.glassfish.jersey.containers
39 | jersey-container-servlet-core
40 | 2.25
41 |
42 |
43 |
44 | org.eclipse.jetty
45 | jetty-server
46 | 9.4.17.v20190418
47 |
48 |
49 |
50 | org.eclipse.jetty
51 | jetty-servlet
52 | 9.3.20.v20170531
53 |
54 |
55 |
56 |
57 | org.glassfish.hk2
58 | hk2-metadata-generator
59 | 2.4.0
60 |
61 |
62 |
63 |
64 |
65 |
66 | jetty9-run
67 |
68 |
69 |
70 | org.eclipse.jetty
71 | jetty-maven-plugin
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/jersey2-jetty-hk2/src/main/java/org/hotswap/agent/example/jersey/Jersey2App.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.jersey;
2 |
3 | import org.eclipse.jetty.server.Server;
4 | import org.eclipse.jetty.servlet.ServletContextHandler;
5 | import org.eclipse.jetty.servlet.ServletHolder;
6 | import org.glassfish.jersey.servlet.ServletContainer;
7 |
8 | public class Jersey2App {
9 | public static void main(String[] args) throws Exception {
10 |
11 | MyApplication config = new MyApplication();
12 | ServletHolder jerseyServlet
13 | = new ServletHolder(new ServletContainer(config));
14 |
15 | Server server = new Server(8080);
16 | ServletContextHandler context
17 | = new ServletContextHandler(server, "/");
18 | context.addServlet(jerseyServlet, "/*");
19 |
20 | server.start();
21 | server.join();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/jersey2-jetty-hk2/src/main/java/org/hotswap/agent/example/jersey/Jersey2Resource.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.jersey;
2 |
3 | import javax.inject.Inject;
4 | import javax.ws.rs.GET;
5 | import javax.ws.rs.Path;
6 |
7 | /**
8 | * Jersey resource.
9 | */
10 | @Path("/")
11 | public class Jersey2Resource {
12 |
13 | @Inject
14 | TestService testService;
15 |
16 | @Inject
17 | TestService2 testService2;
18 |
19 | /**
20 | * Access this resource throw an HTTP request on /rest/jersey1/hello URI.
21 | *
22 | * @return 'Hello from Jersey1!' string
23 | */
24 | @GET
25 | @Path("/hello")
26 | public String hello() {
27 | return testService2.sayHello();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/jersey2-jetty-hk2/src/main/java/org/hotswap/agent/example/jersey/MyApplication.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.jersey;
2 |
3 | import org.glassfish.jersey.server.ResourceConfig;
4 |
5 | public class MyApplication extends ResourceConfig {
6 | public MyApplication() {
7 | register(new MyApplicationBinder());
8 | packages(true, "org.hotswap.agent.example.jersey");
9 | }}
10 |
--------------------------------------------------------------------------------
/jersey2-jetty-hk2/src/main/java/org/hotswap/agent/example/jersey/MyApplicationBinder.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.jersey;
2 |
3 | import org.glassfish.hk2.utilities.binding.AbstractBinder;
4 |
5 | public class MyApplicationBinder extends AbstractBinder {
6 | @Override
7 | protected void configure() {
8 | bind(TestService.class).to(TestService.class);
9 | bind(TestService2.class).to(TestService2.class);
10 | bind(TestService3.class).to(TestService3.class);
11 | }
12 | }
--------------------------------------------------------------------------------
/jersey2-jetty-hk2/src/main/java/org/hotswap/agent/example/jersey/TestService.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.jersey;
2 |
3 | import org.jvnet.hk2.annotations.Service;
4 |
5 | @Service
6 | public class TestService {
7 | public String sayHello() {
8 | return "hello";
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/jersey2-jetty-hk2/src/main/java/org/hotswap/agent/example/jersey/TestService2.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.jersey;
2 |
3 | import javax.inject.Inject;
4 |
5 | import org.jvnet.hk2.annotations.Service;
6 |
7 | @Service
8 | public class TestService2 {
9 |
10 | // @Inject
11 | // TestService3 service3;
12 |
13 | public String sayHello() {
14 | return "hello2";
15 | // return service3.sayHello();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/jersey2-jetty-hk2/src/main/java/org/hotswap/agent/example/jersey/TestService3.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.jersey;
2 |
3 | import org.jvnet.hk2.annotations.Service;
4 |
5 | @Service
6 | public class TestService3 {
7 | public String sayHello() {
8 | return "hello3";
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/jersey2-jetty-hk2/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Jersey2App
6 | org.glassfish.jersey.servlet.ServletContainer
7 |
8 | jersey.config.server.provider.packages
9 | org.hotswap.agent.exemple.jersey
10 |
11 |
12 |
13 | Jersey2App
14 | /rest/*
15 |
16 |
--------------------------------------------------------------------------------
/jersey2/README.md:
--------------------------------------------------------------------------------
1 | Run this sample with:
2 | > 'mvn clean package jetty:run -Pjetty9-run'
3 |
4 | Then open:
5 | > http://localhost:8080/rest/jersey2/hello
--------------------------------------------------------------------------------
/jersey2/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | hotswap-agent-examples-aggregator
7 | org.hotswapagent
8 | 1.4.2-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | jersey2
13 |
14 |
15 |
16 | org.glassfish.jersey.core
17 | jersey-server
18 | 2.14
19 |
20 |
21 | org.glassfish.jersey.containers
22 | jersey-container-servlet-core
23 | 2.14
24 |
25 |
26 | org.eclipse.jetty
27 | jetty-server
28 | 9.4.17.v20190418
29 | provided
30 |
31 |
32 |
33 |
34 |
35 | jetty9-run
36 |
37 |
38 |
39 | org.eclipse.jetty
40 | jetty-maven-plugin
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/jersey2/src/main/java/org/hotswap/agent/exemple/jersey/Jersey2Resource.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.exemple.jersey;
2 |
3 | import javax.ws.rs.GET;
4 | import javax.ws.rs.Path;
5 |
6 | /**
7 | * Jersey resource.
8 | */
9 | @Path("/jersey2")
10 | public class Jersey2Resource {
11 |
12 | /**
13 | * Access this resource throw an HTTP request on /rest/jersey1/hello URI.
14 | *
15 | * @return 'Hello from Jersey1!' string
16 | */
17 | @GET
18 | @Path("/hello")
19 | public String hello() {
20 | return "Hello from Jersey 2!";
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/jersey2/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | Jersey2App
6 | org.glassfish.jersey.servlet.ServletContainer
7 |
8 | jersey.config.server.provider.packages
9 | org.hotswap.agent.exemple.jersey
10 |
11 |
12 |
13 | Jersey2App
14 | /rest/*
15 |
16 |
--------------------------------------------------------------------------------
/plain-java/README.md:
--------------------------------------------------------------------------------
1 | Plain java example
2 | ==================
3 |
4 | Example of application setup with plain Java (without any framework) and core HotswapAgent features.
5 |
6 | Unit tests include:
7 |
8 | * extraClasspath property - load classes and resources from alternative location
9 | * watchResources property - load a resource from alternative location only after it is modified
10 | * autoHotswap property - change class definition at runtime after .class file is modified
11 |
12 | Maven-antrun is used to compile/copy files from java-extra, java-hotswap and resources-extra folders into
13 | target folders to simulate extraClasspath/watchResources directories.
14 |
15 | This example depends only on hotswap-agent-core (runs with `-XXaltjvm=dcevm -javaagent:hotswap-agent-core.jar`).
16 |
17 | ### extraClasspath
18 |
19 | 1. Class `org.hotswap.agent.example.HelloWorld` is located in both src/main/java and src/main/java-extra,
20 | on project assembly (`mvn package`) it becomes target/classes and target/extra.
21 | 1. The agent is configured to add extra classpath directory target/extra
22 | (hotswap-agent.properties contains property `extraClasspath=target/extra`).
23 | 1. Class definition from target/extra should hence precede definition from target/classes
24 | 1. HelloWorld.hello() should return "Hello World Extra".
25 |
26 | Similarly for resources - directory resources/extra becomes target/extra and file test.properties should
27 | be loaded from target/extra instead of target/classes.
28 |
29 | ### watchResources
30 | Some resources may be modified during assembly process from src/main/resources to target/classes (e.g. maven resource
31 | filtering) and hence it is not possible to use extraClasspath to watch directly src/main/resources. Use instead
32 | watchProperties to return resource from the directory after a change only. It is up the user to modify only resources
33 | without filtering.
34 |
35 | In this example target/classes/testWatch.properties contains "Hello World" and target/watch/testWatch.properties
36 | contains "This should never happen - before change contents should be read from target/classes." As the string
37 | suggests, although the hotswap-agent.properties setup contains `watchResources=target/watch, original file
38 | should be returned. Only after the test "manually" replaces target/watch/testWatch.properties with
39 | target/watch/testWatchReplace.properties (and hence IS modified), new value "Hello World Watch" is returned.
40 |
41 | ### autoHotswap
42 | If hotswap-agent.properties setup contains `autoHotswap=true`, all class files on classpath (original +
43 | extraClasspath) are watched for changes (note that only plain .class files on local filesystem and not in JAR can
44 | be watched). If the filesystem triggers a change, JVM hotswap is automatically launched for the file.
45 |
46 | HelloWorldHotswapTest loads the class `org.hotswap.agent.example.HelloWorldHotswap` bytecode, renames
47 | it to HelloWorld and replaces HelloWorldHotswap.class file in target/classes. This triggers the change
48 | and new class version is introduced. HelloWorld.hello() will then return new value "Hello World Hotswap".
49 |
--------------------------------------------------------------------------------
/plain-java/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | org.hotswapagent
9 | hotswap-agent-examples-aggregator
10 | 1.4.2-SNAPSHOT
11 |
12 |
13 | org.hotswap.examples
14 | plain-java
15 |
16 |
17 |
18 |
19 | org.apache.maven.plugins
20 | maven-antrun-plugin
21 | 1.7
22 |
23 |
24 | generate-sources
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 |
51 |
52 |
53 |
54 |
55 |
56 | run
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | org.hotswapagent
67 | hotswap-agent-core
68 | ${project.version}
69 | provided
70 |
71 |
72 |
73 | junit
74 | junit
75 | 4.12
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/plain-java/run-tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # simple script to run test
3 | # this should be replaced by build sever in the future
4 |
5 | # fail with first failed test
6 | set -e
7 |
8 | # run clean install (with all integration tests)
9 | function test {
10 | echo "Running tests for plain Java"
11 | mvn clean install
12 | }
13 |
14 | test
--------------------------------------------------------------------------------
/plain-java/src/main/java-extra/org/hotswap/agent/example/HelloAnnotation.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Test annotation.
10 | */
11 | @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface HelloAnnotation {
14 | public String value() default "";
15 | }
16 |
--------------------------------------------------------------------------------
/plain-java/src/main/java-extra/org/hotswap/agent/example/HelloInterface.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | /**
4 | * Interface to test anonymous classes.
5 | */
6 | public interface HelloInterface {
7 | String hello(String dummy);
8 | }
9 |
--------------------------------------------------------------------------------
/plain-java/src/main/java-extra/org/hotswap/agent/example/HelloWorld.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | /**
4 | * Hello world class.
5 | */
6 | @HelloAnnotation("hello extra")
7 | public class HelloWorld {
8 | public static String hello() {
9 | return "Hello World Extra";
10 | }
11 |
12 | @HelloAnnotation("hello extra")
13 | public String hello(@HelloAnnotation("par extra") String par) {
14 | return "Hello Extra " + par;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/plain-java/src/main/java-extra/org/hotswap/agent/example/HelloWorldHotswap.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | /**
4 | * Hello world class to be replaced by hotswap.
5 | */
6 | @HelloAnnotation("hello extra")
7 | public class HelloWorldHotswap {
8 | public static String hello() {
9 | return "Hello World Extra";
10 | }
11 |
12 | // create new annonymous class before HelloInterface. HotswapperPlugin should kick in.
13 | public void dummy() {
14 | new Cloneable() {};
15 | }
16 |
17 | @HelloAnnotation("hello extra")
18 | public String hello(final @HelloAnnotation("par extra") String par) {
19 | HelloInterface anonymous = new HelloInterface() {
20 | @Override
21 | public String hello(String dummy) {
22 | return "Hello Extra " + par;
23 | }
24 | };
25 | return anonymous.hello(null);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/plain-java/src/main/java-hotswap/org/hotswap/agent/example/HelloAnnotation.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Test annotation.
10 | */
11 | @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface HelloAnnotation {
14 | public String value() default "";
15 | }
16 |
--------------------------------------------------------------------------------
/plain-java/src/main/java-hotswap/org/hotswap/agent/example/HelloInterface.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | /**
4 | * Interface to test anonymous classes.
5 | */
6 | public interface HelloInterface {
7 | String hello(String dummy);
8 | }
9 |
--------------------------------------------------------------------------------
/plain-java/src/main/java-hotswap/org/hotswap/agent/example/HelloWorldHotswap.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | import java.lang.Cloneable;
4 |
5 | /**
6 | * Hello world class.
7 | */
8 | @HelloAnnotation("hello hotswap")
9 | public class HelloWorldHotswap {
10 | public static String hello() {
11 | return helloPrivate();
12 | }
13 |
14 | @HelloAnnotation("hello hotswap")
15 | public String hello(final @HelloAnnotation("par hotswap") String par) {
16 | HelloInterface anonymous = new HelloInterface() {
17 | @Override
18 | @HelloAnnotation("hello hotswap")
19 | public String hello(final @HelloAnnotation("par hotswap") String dummy) {
20 | return "Hello Hotswap " + par;
21 | }
22 | };
23 | return anonymous.hello(null);
24 | }
25 |
26 | // chage ordering of annonymous classes. HotswapperPlugin should kick in.
27 | public void dummy() {
28 | new Cloneable() {};
29 | }
30 |
31 | private static String helloPrivate() {
32 | return "Hello World Hotswap";
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/plain-java/src/main/java/org/hotswap/agent/example/HelloAnnotation.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Test annotation.
10 | */
11 | @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface HelloAnnotation {
14 | public String value() default "";
15 | }
16 |
--------------------------------------------------------------------------------
/plain-java/src/main/java/org/hotswap/agent/example/HelloInterface.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | /**
4 | * Interface to test anonymous classes.
5 | */
6 | public interface HelloInterface {
7 | String hello(String dummy);
8 | }
9 |
--------------------------------------------------------------------------------
/plain-java/src/main/java/org/hotswap/agent/example/HelloWorld.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | /**
4 | * Hello world class to be replaced by extraClasspath.
5 | */
6 | @HelloAnnotation("hello")
7 | public class HelloWorld {
8 | public static String hello() {
9 | return "Hello World";
10 | }
11 |
12 | @HelloAnnotation("hello")
13 | public String hello(@HelloAnnotation("par") String par) {
14 | return "Hello " + par;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/plain-java/src/main/java/org/hotswap/agent/example/HelloWorldHotswap.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | /**
4 | * Hello world class to be replaced by hotswap.
5 | */
6 | @HelloAnnotation("hello")
7 | public class HelloWorldHotswap {
8 | public static String hello() {
9 | return "Hello World";
10 | }
11 |
12 | // create new annonymous class before HelloInterface. HotswapperPlugin should kick in.
13 | public void dummy() {
14 | new Cloneable() {};
15 | }
16 |
17 | @HelloAnnotation("hello")
18 | public String hello(final @HelloAnnotation("par") String par) {
19 | HelloInterface anonymous = new HelloInterface() {
20 | @Override
21 | public String hello(String dummy) {
22 | return "Hello " + par;
23 | }
24 | };
25 | return anonymous.hello(null);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/plain-java/src/main/resources-extra/test.properties:
--------------------------------------------------------------------------------
1 | hello=Hello World Extra
--------------------------------------------------------------------------------
/plain-java/src/main/resources-watch/testWatch.properties:
--------------------------------------------------------------------------------
1 | hello=This should never happen - before change contents should be read from target/classes.
--------------------------------------------------------------------------------
/plain-java/src/main/resources-watch/testWatchReplace.properties:
--------------------------------------------------------------------------------
1 | hello=Hello World Watch
--------------------------------------------------------------------------------
/plain-java/src/main/resources/hotswap-agent.properties:
--------------------------------------------------------------------------------
1 | extraClasspath=target/extra
2 | watchResources=target/watch
3 | autoHotswap=true
4 |
5 | LOGGER=debug
6 |
--------------------------------------------------------------------------------
/plain-java/src/main/resources/test.properties:
--------------------------------------------------------------------------------
1 | hello=Hello World
--------------------------------------------------------------------------------
/plain-java/src/main/resources/testWatch.properties:
--------------------------------------------------------------------------------
1 | hello=Hello World
--------------------------------------------------------------------------------
/plain-java/src/test/java/org/hotswap/agent/example/HelloWorldTest.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | import org.hotswap.agent.util.test.WaitHelper;
4 | import org.junit.Assert;
5 | import org.junit.Test;
6 |
7 | import java.io.IOException;
8 | import java.lang.reflect.Method;
9 | import java.nio.file.Files;
10 | import java.nio.file.Path;
11 | import java.nio.file.Paths;
12 | import java.nio.file.StandardCopyOption;
13 | import java.util.ResourceBundle;
14 |
15 | /**
16 | * Test loading classes and resources according to extraClasspath property.
17 | */
18 | public class HelloWorldTest {
19 | @Test
20 | public void extraClassPathClassStaticTest() {
21 | Assert.assertEquals("Assert class from target/extra is used.", "Hello World Extra", HelloWorld.hello());
22 | }
23 |
24 | @Test
25 | public void extraClassPathClassTest() {
26 | Assert.assertEquals("Assert class from target/extra is used.", "Hello Extra par", new HelloWorld().hello("par"));
27 | }
28 |
29 | @Test
30 | public void extraClassPathAnnotationTest() throws Exception {
31 | Class clazz = HelloWorld.class;
32 |
33 | HelloAnnotation clazzAnnotation = (HelloAnnotation) clazz.getAnnotation(HelloAnnotation.class);
34 | Assert.assertEquals("hello extra", clazzAnnotation.value());
35 |
36 | Method helloMethod = clazz.getDeclaredMethod("hello", String.class);
37 | HelloAnnotation methodAnnotation = (HelloAnnotation) helloMethod.getAnnotation(HelloAnnotation.class);
38 | Assert.assertEquals("hello extra", methodAnnotation.value());
39 | HelloAnnotation paramAnnotation = (HelloAnnotation) helloMethod.getParameterAnnotations()[0][0];
40 | Assert.assertEquals("par extra", paramAnnotation.value());
41 | }
42 |
43 | @Test
44 | public void extraClassPathResourceTest() {
45 | String hello = ResourceBundle.getBundle("test").getString("hello");
46 | Assert.assertEquals("Assert resource from target/extra is used.", "Hello World Extra", hello);
47 | }
48 |
49 | @Test
50 | public void extraClassPathWatchResourceTest() throws IOException, InterruptedException {
51 | // check before change
52 | String hello = ResourceBundle.getBundle("testWatch").getString("hello");
53 | Assert.assertEquals("Assert original resource from target/classes is used.", "Hello World", hello);
54 |
55 | // replace the file in watched dir
56 | Path source = Paths.get("target/watch/testWatchReplace.properties");
57 | Path target = Paths.get("target/watch/testWatch.properties");
58 | Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
59 | Thread.sleep(2000);
60 |
61 | // wait for the hotswap
62 | boolean result = WaitHelper.waitForCommand(new WaitHelper.Command() {
63 | @Override
64 | public boolean result() throws Exception {
65 | ResourceBundle.clearCache();
66 | String hello = ResourceBundle.getBundle("testWatch").getString("hello");
67 | return "Hello World Watch".equals(hello);
68 | }
69 | });
70 |
71 | // check that agentexamples works
72 | Assert.assertTrue("Assert modified target/watch/testWatch.properties is used.", result);
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/plain-servlet/README.md:
--------------------------------------------------------------------------------
1 | Plain servlet example
2 | =====================
3 |
4 | Example of application setup inside servlet containser / J2EE application server (without any
5 | additional framework) and HotswapAgent including all plugins.
6 |
7 | Unit tests include:
8 |
9 | * extraClasspath property - load classes and resources from alternative location
10 | * watchResources property - load a resource from alternative location only after it is modified
11 | * autoHotswap property - change class definition at runtime after .class file is modified
12 |
13 | Maven-antrun is used to compile/copy files from java-extra, java-hotswap and resources-extra folders into
14 | target folders to simulate extraClasspath/watchResources directories.
15 |
16 | This example does pretty the same as plain-java, but checks the value as HTTP response strings.
17 | See plain-java/README.md for description of used hotswap-agent.properties.
18 |
19 | This example depends on hotswap-agent.jar (runs with `-XXaltjvm=dcevm -javaagent:hotswap-agent.jar`) to
20 | check that all plugins are
21 |
22 | Application server support
23 | ==========================
24 | See run-test.sh for list of tested servers.
25 |
--------------------------------------------------------------------------------
/plain-servlet/run-tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # simple script to run various containers setup
3 | # this should be replaced by build sever in the future
4 |
5 | # fail with first failed test
6 | set -e
7 |
8 | # run clean install (with all integration tests)
9 | function test {
10 | echo "Running with container $1"
11 | mvn -Dhotswapagent.jar=$2 clean verify -P $1
12 | }
13 |
14 | if [ -z "$HOT_SWAP_AGENT"]; then
15 | echo "HOT_SWAP_AGENT is not set, pls. specify where the HotSwapAgent jar location"
16 | exit 1
17 | fi
18 |
19 | # Older versions of Jetty works as well, but are configured only with embedded configuration, which does not support jvmargs
20 | # it cannot be launched automatically (set -javaagent). To launch the test, set MAVEN_OPTS and run manually.
21 | test jetty7 ${HOT_SWAP_AGENT}
22 | test jetty8 ${HOT_SWAP_AGENT}
23 | test jetty9 ${HOT_SWAP_AGENT}
24 |
25 | # Tomcat should be Ok.
26 | test tomcat6 ${HOT_SWAP_AGENT}
27 | test tomcat7 ${HOT_SWAP_AGENT}
28 | test tomcat8 ${HOT_SWAP_AGENT}
29 | test tomcat9 ${HOT_SWAP_AGENT}
30 |
31 | # Almost all hotswap agent properties do not work :-(
32 | #test jboss5x
33 | # JBoss 8 is OSGI based and catalina WebappLoader is not used anymore
34 | #test jboss8
35 |
36 | # GlassFish is based on OSGI, need to first resolve
37 | #test glassfish3
38 | #test glassfish4
39 |
40 | # Need to download manually and setup, did not try yet
41 | # test weblogic12x
--------------------------------------------------------------------------------
/plain-servlet/src/main/java-extra/org/hotswap/agent/example/HelloWorldBaseServlet.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | import javax.servlet.*;
4 | import java.io.IOException;
5 | import java.util.ResourceBundle;
6 |
7 | /**
8 | * Base servlet with template method and several resources.
9 | */
10 | public abstract class HelloWorldBaseServlet implements Servlet {
11 |
12 | /**
13 | * Template method to return Hello World text modifications.
14 | */
15 | protected abstract String getHello();
16 |
17 | /**
18 | * Return basic resource, it should be handled from target/extra directory.
19 | */
20 | protected String getHelloResource() {
21 | ResourceBundle.clearCache();
22 | return ResourceBundle.getBundle("test").getString("hello");
23 | }
24 |
25 | /**
26 | * Return content of testWatch.properties. It should be resolved to target/classes until
27 | * resources-watch/testWatch.properties is modified, then it should return the new value.
28 | */
29 | protected String getHelloResourceWatch() {
30 | ResourceBundle.clearCache();
31 | return ResourceBundle.getBundle("testWatch").getString("hello");
32 | }
33 |
34 | @Override
35 | public void init(ServletConfig config) throws ServletException {
36 |
37 | }
38 |
39 | @Override
40 | public ServletConfig getServletConfig() {
41 | return null;
42 | }
43 |
44 | @Override
45 | public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
46 | String param = req.getParameter("method");
47 | if ("helloResource".equals(param)) {
48 | res.getWriter().write(getHelloResource());
49 | } else if ("helloResourceWatch".equals(param)) {
50 | res.getWriter().write(getHelloResourceWatch());
51 | } else {
52 | // default hello world
53 | res.getWriter().write(getHello());
54 | }
55 | }
56 |
57 |
58 | @Override
59 | public String getServletInfo() {
60 | return null;
61 | }
62 |
63 | @Override
64 | public void destroy() {
65 |
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/plain-servlet/src/main/java-extra/org/hotswap/agent/example/HelloWorldServlet.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | /**
4 | * Simple Hello World - this should override the default.
5 | */
6 | public class HelloWorldServlet extends HelloWorldBaseServlet {
7 | @Override
8 | protected String getHello() {
9 | return "Hello World Extra";
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/plain-servlet/src/main/java-extra/org/hotswap/agent/example/HelloWorldServletHotswap.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | /**
4 | * Hello world class to be replaced by hotswap.
5 | */
6 | public class HelloWorldServletHotswap extends HelloWorldBaseServlet {
7 | @Override
8 | protected String getHello() {
9 | return "Hello World Extra";
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/plain-servlet/src/main/java-hotswap/org/hotswap/agent/example/HelloWorldBaseServlet.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | import javax.servlet.*;
4 | import java.io.IOException;
5 | import java.util.ResourceBundle;
6 |
7 | /**
8 | * Base servlet with template method and several resources.
9 | */
10 | public abstract class HelloWorldBaseServlet implements Servlet {
11 |
12 | /**
13 | * Template method to return Hello World text modifications.
14 | */
15 | protected abstract String getHello();
16 |
17 | /**
18 | * Return basic resource, it should be handled from target/extra directory.
19 | */
20 | protected String getHelloResource() {
21 | ResourceBundle.clearCache();
22 | return ResourceBundle.getBundle("test").getString("hello");
23 | }
24 |
25 | /**
26 | * Return content of testWatch.properties. It should be resolved to target/classes until
27 | * resources-watch/testWatch.properties is modified, then it should return the new value.
28 | */
29 | protected String getHelloResourceWatch() {
30 | ResourceBundle.clearCache();
31 | return ResourceBundle.getBundle("testWatch").getString("hello");
32 | }
33 |
34 | @Override
35 | public void init(ServletConfig config) throws ServletException {
36 |
37 | }
38 |
39 | @Override
40 | public ServletConfig getServletConfig() {
41 | return null;
42 | }
43 |
44 | @Override
45 | public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
46 | String param = req.getParameter("method");
47 | if ("helloResource".equals(param)) {
48 | res.getWriter().write(getHelloResource());
49 | } else if ("helloResourceWatch".equals(param)) {
50 | res.getWriter().write(getHelloResourceWatch());
51 | } else {
52 | // default hello world
53 | res.getWriter().write(getHello());
54 | }
55 | }
56 |
57 |
58 | @Override
59 | public String getServletInfo() {
60 | return null;
61 | }
62 |
63 | @Override
64 | public void destroy() {
65 |
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/plain-servlet/src/main/java-hotswap/org/hotswap/agent/example/HelloWorldServletHotswap.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | /**
4 | * Hello world class - this will be used to hotswap the package in extra.
5 | */
6 | public class HelloWorldServletHotswap extends HelloWorldBaseServlet {
7 | @Override
8 | protected String getHello() {
9 | return "Hello World Hotswap";
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/plain-servlet/src/main/java/org/hotswap/agent/example/HelloWorldBaseServlet.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | import javax.servlet.*;
4 | import java.io.IOException;
5 | import java.util.ResourceBundle;
6 |
7 | /**
8 | * Base servlet with template method and several resources.
9 | */
10 | public abstract class HelloWorldBaseServlet implements Servlet {
11 |
12 | protected HelloWorldBaseServlet() {
13 | }
14 |
15 | /**
16 | * Template method to return Hello World text modifications.
17 | */
18 | protected abstract String getHello();
19 |
20 | /**
21 | * Return basic resource, it should be handled from target/extra directory.
22 | */
23 | protected String getHelloResource() {
24 | ResourceBundle.clearCache();
25 | return ResourceBundle.getBundle("test").getString("hello");
26 | }
27 |
28 | /**
29 | * Return content of testWatch.properties. It should be resolved to target/classes until
30 | * resources-watch/testWatch.properties is modified, then it should return the new value.
31 | */
32 | protected String getHelloResourceWatch() {
33 | ResourceBundle.clearCache();
34 | return ResourceBundle.getBundle("testWatch").getString("hello");
35 | }
36 |
37 | @Override
38 | public void init(ServletConfig config) throws ServletException {
39 |
40 | }
41 |
42 | @Override
43 | public ServletConfig getServletConfig() {
44 | return null;
45 | }
46 |
47 | @Override
48 | public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
49 | String param = req.getParameter("method");
50 | if ("helloResource".equals(param)) {
51 | res.getWriter().write(getHelloResource());
52 | } else if ("helloResourceWatch".equals(param)) {
53 | res.getWriter().write(getHelloResourceWatch());
54 | } else {
55 | // default hello world
56 | res.getWriter().write(getHello());
57 | }
58 | }
59 |
60 |
61 | @Override
62 | public String getServletInfo() {
63 | return null;
64 | }
65 |
66 | @Override
67 | public void destroy() {
68 |
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/plain-servlet/src/main/java/org/hotswap/agent/example/HelloWorldServlet.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | /**
4 | * Simple Hello World to be replaced by extra
5 | */
6 | public class HelloWorldServlet extends HelloWorldBaseServlet {
7 |
8 | @Override
9 | protected String getHello() {
10 | return "Hello World";
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/plain-servlet/src/main/java/org/hotswap/agent/example/HelloWorldServletHotswap.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | /**
4 | * Hello world class to be replaced by hotswap.
5 | */
6 | public class HelloWorldServletHotswap extends HelloWorldBaseServlet {
7 | @Override
8 | protected String getHello() {
9 | return "Hello Worlda";
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/plain-servlet/src/main/resources-extra/test.properties:
--------------------------------------------------------------------------------
1 | hello=Hello World Extra
--------------------------------------------------------------------------------
/plain-servlet/src/main/resources-watch/testWatch.properties:
--------------------------------------------------------------------------------
1 | hello=This should never happen - before change contents should be read from target/classes.
--------------------------------------------------------------------------------
/plain-servlet/src/main/resources-watch/testWatchReplace.properties:
--------------------------------------------------------------------------------
1 | hello=Hello World Watch
--------------------------------------------------------------------------------
/plain-servlet/src/main/resources/hotswap-agent.properties:
--------------------------------------------------------------------------------
1 | # ${basedir} will be replaced by Maven true .. option
2 | extraClasspath=${basedir}/target/extra
3 | watchResources=${basedir}/target/watch
4 |
5 | # webapp-extra will be copied into target directory during maven build.
6 | # for manual tests from IDE change this to ${basedir}/src/main/webapp-extra
7 | webappDir=${basedir}/target/webapp-extra
8 |
9 | LOGGER=debug
10 |
--------------------------------------------------------------------------------
/plain-servlet/src/main/resources/test.properties:
--------------------------------------------------------------------------------
1 | hello=Hello World
--------------------------------------------------------------------------------
/plain-servlet/src/main/resources/testWatch.properties:
--------------------------------------------------------------------------------
1 | hello=Hello World
--------------------------------------------------------------------------------
/plain-servlet/src/main/webapp-extra/hello.jsp:
--------------------------------------------------------------------------------
1 | Hello World Extra
--------------------------------------------------------------------------------
/plain-servlet/src/main/webapp/META-INF/context.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/plain-servlet/src/main/webapp/WEB-INF/jboss-web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | /plain-servlet
4 |
5 |
--------------------------------------------------------------------------------
/plain-servlet/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | HelloWorld
6 | org.hotswap.agent.example.HelloWorldServlet
7 |
8 |
9 | HelloWorld
10 | /hello
11 |
12 |
13 |
14 | HelloWorldHotswap
15 | org.hotswap.agent.example.HelloWorldServletHotswap
16 |
17 |
18 | HelloWorldHotswap
19 | /helloHotswap
20 |
21 |
22 |
--------------------------------------------------------------------------------
/plain-servlet/src/main/webapp/hello.jsp:
--------------------------------------------------------------------------------
1 | Hello World
--------------------------------------------------------------------------------
/plain-servlet/src/test/java/org/hotswap/agent/example/HelloWorldServletHotswapIT.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | import org.apache.http.HttpResponse;
4 | import org.apache.http.client.methods.HttpGet;
5 | import org.apache.http.client.methods.HttpUriRequest;
6 | import org.apache.http.impl.client.HttpClientBuilder;
7 | import org.apache.http.util.EntityUtils;
8 | import org.hotswap.agent.util.test.WaitHelper;
9 | import org.junit.Assert;
10 | import org.junit.Test;
11 |
12 | import java.io.IOException;
13 | import java.nio.file.Files;
14 | import java.nio.file.Path;
15 | import java.nio.file.Paths;
16 | import java.nio.file.StandardCopyOption;
17 |
18 | import static org.junit.Assert.assertEquals;
19 |
20 | /**
21 | * Test autoHotswap of classes after change
22 | */
23 | public class HelloWorldServletHotswapIT {
24 |
25 | @Test
26 | public void extraClassPathHotswapTest() throws IOException, InterruptedException {
27 | final HttpUriRequest request = new HttpGet(HelloWorldServletIT.ENDPOINT + "helloHotswap");
28 |
29 | // replace the class file in extraClasspath (classloader looks into this directory)
30 | // autoHotswap should discover this change and reload the class
31 | String helloWorldFile = HelloWorldServletHotswap.class.getName().replace(".", "/") + ".class";
32 | Path source = Paths.get("target/hotswap/" + helloWorldFile);
33 | Path target = Paths.get("target/extra/" + helloWorldFile);
34 | Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
35 |
36 | // wait for the hotswap
37 | boolean result = WaitHelper.waitForCommand(new WaitHelper.Command() {
38 | @Override
39 | public boolean result() throws Exception {
40 | HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request);
41 | String result = EntityUtils.toString(httpResponse.getEntity());
42 |
43 | return "Hello World Hotswap".equals(result);
44 | }
45 | }, 2000);
46 |
47 | // check that agentexamples works
48 | Assert.assertTrue("Assert hotswapped class in extra is used.", result);
49 | }
50 |
51 | }
--------------------------------------------------------------------------------
/plain-servlet/src/test/java/org/hotswap/agent/example/HelloWorldServletIT.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | import org.apache.http.HttpResponse;
4 | import org.apache.http.HttpStatus;
5 | import org.apache.http.client.methods.HttpGet;
6 | import org.apache.http.client.methods.HttpUriRequest;
7 | import org.apache.http.impl.client.HttpClientBuilder;
8 | import org.apache.http.util.EntityUtils;
9 | import org.hotswap.agent.util.test.WaitHelper;
10 | import org.junit.Assert;
11 | import org.junit.Test;
12 |
13 | import java.io.IOException;
14 | import java.nio.file.Files;
15 | import java.nio.file.Path;
16 | import java.nio.file.Paths;
17 | import java.nio.file.StandardCopyOption;
18 | import java.util.ResourceBundle;
19 |
20 | import static org.junit.Assert.assertEquals;
21 |
22 | public class HelloWorldServletIT {
23 | public static final String ENDPOINT = "http://localhost:8080/plain-servlet/";
24 |
25 | @Test
26 | public void testUpAndRunning() throws Exception {
27 | HttpUriRequest request = new HttpGet(ENDPOINT + "hello");
28 | HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request);
29 |
30 | assertEquals(HttpStatus.SC_OK, httpResponse.getStatusLine().getStatusCode());
31 | }
32 |
33 | @Test
34 | public void testHello() throws Exception {
35 | HttpUriRequest request = new HttpGet(ENDPOINT + "hello");
36 | HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request);
37 |
38 | assertEquals("Hello World Extra", EntityUtils.toString(httpResponse.getEntity()));
39 | }
40 |
41 | @Test
42 | public void testHelloResourceExtraPath() throws Exception {
43 | HttpUriRequest request = new HttpGet(ENDPOINT + "hello?method=helloResource");
44 | HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request);
45 |
46 | assertEquals("Hello World Extra", EntityUtils.toString(httpResponse.getEntity()));
47 | }
48 |
49 | @Test
50 | public void extraClassPathWatchResourceTest() throws IOException, InterruptedException {
51 | final HttpUriRequest request = new HttpGet(ENDPOINT + "hello?method=helloResourceWatch");
52 |
53 | // check before change
54 | String hello = ResourceBundle.getBundle("testWatch").getString("hello");
55 | Assert.assertEquals("Assert original resource from target/classes is used.", "Hello World", hello);
56 |
57 | // replace the file in watched dir
58 | Path source = Paths.get("target/watch/testWatchReplace.properties");
59 | Path target = Paths.get("target/watch/testWatch.properties");
60 | Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
61 |
62 | // wait for the hotswap
63 | boolean result = WaitHelper.waitForCommand(new WaitHelper.Command() {
64 | @Override
65 | public boolean result() throws Exception {
66 | HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request);
67 |
68 | String hello = EntityUtils.toString(httpResponse.getEntity());
69 | System.err.println(hello);
70 | return "Hello World Watch".equals(hello);
71 | }
72 | }, 4000);
73 |
74 | // check that agentexamples works
75 | Assert.assertTrue("Assert modified target/watch/testWatch.properties is used.", result);
76 | }
77 | }
--------------------------------------------------------------------------------
/plain-servlet/src/test/java/org/hotswap/agent/example/HelloWorldServletJspIT.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | import org.apache.http.HttpResponse;
4 | import org.apache.http.HttpStatus;
5 | import org.apache.http.client.methods.HttpGet;
6 | import org.apache.http.client.methods.HttpUriRequest;
7 | import org.apache.http.impl.client.HttpClientBuilder;
8 | import org.apache.http.util.EntityUtils;
9 | import org.junit.Test;
10 |
11 | import java.io.IOException;
12 |
13 | import static org.junit.Assert.assertEquals;
14 |
15 | /**
16 | * Test webapp property.
17 | */
18 | public class HelloWorldServletJspIT {
19 |
20 | @Test
21 | public void extraWebappDirHotswapTest() throws IOException, InterruptedException {
22 | final HttpUriRequest request = new HttpGet(HelloWorldServletIT.ENDPOINT + "hello.jsp");
23 | HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request);
24 |
25 | assertEquals(HttpStatus.SC_OK, httpResponse.getStatusLine().getStatusCode());
26 |
27 | assertEquals("Hello World Extra", EntityUtils.toString(httpResponse.getEntity()));
28 | }
29 |
30 | }
--------------------------------------------------------------------------------
/resteasy-app/resteasy-managment/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | org.hotswapagent
6 | resteasy-parent
7 | 1.4.2-SNAPSHOT
8 | ../pom.xml
9 |
10 |
11 | resteasy-managment
12 | war
13 |
14 | resteasy-managment
15 |
16 |
17 |
18 |
19 | ${project.groupId}
20 | resteasy-model
21 | 1.4.2-SNAPSHOT
22 |
23 |
24 |
25 | org.json
26 | json
27 |
28 |
29 |
30 | javax.servlet
31 | javax.servlet-api
32 |
33 |
34 |
35 | commons-dbutils
36 | commons-dbutils
37 |
38 |
39 | javax
40 | javaee-web-api
41 |
42 |
43 |
44 | org.jboss.resteasy
45 | resteasy-jackson-provider
46 | 3.0.9.Final
47 | test
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | src/main/resources
56 | true
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/resteasy-app/resteasy-managment/src/main/java/org/hotswap/agent/example/service/BaseApplication.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.service;
2 | import java.util.Collections;
3 | import java.util.Set;
4 | import javax.ws.rs.ApplicationPath;
5 | import javax.ws.rs.core.Application;
6 |
7 | @ApplicationPath("/Services")
8 | public class BaseApplication extends Application {
9 |
10 | @Override
11 | public Set> getClasses() {
12 | return Collections.emptySet();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/resteasy-app/resteasy-managment/src/main/java/org/hotswap/agent/example/service/PersonManagement.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.service;
2 |
3 | import java.util.Date;
4 | import javax.ws.rs.GET;
5 | import javax.ws.rs.Path;
6 | import javax.ws.rs.Produces;
7 | import javax.ws.rs.core.MediaType;
8 | import org.hotswap.agent.example.model.Person;
9 |
10 | /**
11 | *
12 | * @author christoforosl
13 | */
14 | @Path("/PersonManagement")
15 | @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
16 | public class PersonManagement {
17 |
18 | @GET
19 | @Path("Person")
20 | public Person getPerson() {
21 |
22 | final org.hotswap.agent.example.model.Person ret = new Person();
23 | ret.setBirthDate(new Date());
24 | ret.setFirstName("hotswap ZZZ");
25 | ret.setLastName("test");
26 | ret.setPersonId(1000L);
27 |
28 | return ret;
29 | }
30 |
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/resteasy-app/resteasy-managment/src/main/webapp/WEB-INF/jboss-web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | /resteasy-test
4 |
5 |
--------------------------------------------------------------------------------
/resteasy-app/resteasy-managment/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 30
5 |
6 |
7 |
8 | resteasy-test
9 |
10 | resteasy.scan
11 | false
12 |
13 |
14 | resteasy.resources
15 | org.hotswap.agent.example.service.PersonManagement
16 |
17 |
18 |
19 | resteasy-servlet
20 |
21 | org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
22 |
23 |
24 |
25 | resteasy-servlet
26 | /*
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/resteasy-app/resteasy-managment/src/main/webapp/index.jsp:
--------------------------------------------------------------------------------
1 | <%@page contentType="text/html" pageEncoding="UTF-8"%>
2 |
3 |
4 |
5 |
6 | RestEasy Services
7 |
8 |
9 | RestEasy Services
10 |
11 |
12 |
--------------------------------------------------------------------------------
/resteasy-app/resteasy-managment/src/main/webapp/jboss-web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | /HotSwapAgentTest
4 |
5 |
--------------------------------------------------------------------------------
/resteasy-app/resteasy-managment/src/test/java/org/hotswap/agent/example/test/JSONIgnorePropTest.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.test;
2 |
3 | import java.util.Date;
4 |
5 | import org.codehaus.jackson.map.ObjectMapper;
6 | import org.hotswap.agent.example.model.Person;
7 | import org.junit.Test;
8 |
9 | /**
10 | *
11 | * @author christoforosl
12 | */
13 | public class JSONIgnorePropTest {
14 |
15 | @Test
16 | public void ignoredProperties() throws Exception {
17 |
18 | ObjectMapper mapper = new ObjectMapper();
19 |
20 | Person e = new Person();
21 | e.setBirthDate(new Date());
22 |
23 | String s = mapper.writeValueAsString(e);
24 |
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/resteasy-app/resteasy-model/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | org.hotswapagent
8 | resteasy-parent
9 | 1.4.2-SNAPSHOT
10 | ../pom.xml
11 |
12 |
13 | resteasy-model
14 | jar
15 |
16 | JDK_1.7
17 |
18 | resteasy-model
19 | Project containing all Domain Model objects
20 |
--------------------------------------------------------------------------------
/resteasy-app/resteasy-model/src/main/java/org/hotswap/agent/example/model/Person.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.model;
2 |
3 | import org.codehaus.jackson.annotate.JsonProperty;
4 |
5 | public class Person extends PersonModelBase {
6 |
7 | @JsonProperty
8 | public String getP2() {
9 | return "P2!!";
10 | }
11 | public String getFullName() {
12 |
13 | return this.getFirstName()+ " - " + this.getLastName();
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/run-tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # simple script to run all tests and all versions. It fails with first failure
3 | # this should be replaced by build sever in the future
4 |
5 | # fail with first failed test
6 | set -e
7 |
8 | function test {
9 | echo "Running with Java $1"
10 | export JAVA_HOME=$1
11 |
12 | echo "Resolved version: " `"$JAVA_HOME/bin/java" -version`
13 |
14 | mvn -Dhotswapagent.jar=$2 clean package
15 |
16 | # run tests
17 | cd plain-java; ./run-tests.sh; cd ..
18 | cd spring-boot; ./run-tests.sh; cd ..
19 |
20 | # TODO
21 | # custom-plugin
22 | # cd plain-servlet; ./run-tests.sh; cd ..
23 | # spring-hibernate
24 | # ...
25 | }
26 |
27 | if [ -z "$JAVA_HOME" ]; then
28 | echo "JAVA_HOME is not set"
29 | exit 1
30 | fi
31 |
32 | if [ -z "$HOT_SWAP_AGENT"]; then
33 | echo "HOT_SWAP_AGENT is not set, pls. specify where the HotSwapAgent jar location"
34 | exit 1
35 | fi
36 |
37 | test $JAVA_HOME $HOT_SWAP_AGENT
38 |
--------------------------------------------------------------------------------
/spring-boot-kotlin/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM openjdk:8-jre-slim
2 |
3 | MAINTAINER Jiří Bubník
4 |
5 | VOLUME /tmp
6 | WORKDIR /app/tsm
7 | ADD target/tsm-dms*.jar /app/tsm/tsm-dms.jar
8 | EXPOSE 8082/tcp
9 | ENTRYPOINT ["java","-XX:MaxRAM=300m","-Djava.security.egd=file:/dev/./urandom","-jar","tsm-dms.jar", "--spring.profiles.active=kubernetes"]
10 |
--------------------------------------------------------------------------------
/spring-boot-kotlin/README.md:
--------------------------------------------------------------------------------
1 | # Example applicatin of Spring Boot REST API with Kotlin
2 |
--------------------------------------------------------------------------------
/spring-boot-kotlin/src/main/java/org/hotswap/agent/example/springbootkotlin/ExampleApi.kt:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.springbootkotlin
2 |
3 | import org.springframework.web.bind.annotation.*
4 |
5 | @RestController
6 | @RequestMapping(value = ["/example"])
7 | class ExampleApi {
8 |
9 | @GetMapping("/{test}")
10 | @ResponseBody
11 | fun test(@PathVariable test: String) : String = "hello " + test
12 | }
13 |
--------------------------------------------------------------------------------
/spring-boot-kotlin/src/main/java/org/hotswap/agent/example/springbootkotlin/ExampleApplication.kt:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.springbootkotlin
2 |
3 | import org.springframework.boot.autoconfigure.SpringBootApplication
4 | import org.springframework.boot.runApplication
5 |
6 | @SpringBootApplication
7 | class ExampleApplication
8 |
9 | fun main(args: Array) {
10 | runApplication(*args)
11 | }
12 |
--------------------------------------------------------------------------------
/spring-boot-kotlin/src/main/resources/application.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HotswapProjects/HotswapAgentExamples/6b313ca4e24087f5a05d46f63ddece51cf1e9418/spring-boot-kotlin/src/main/resources/application.yml
--------------------------------------------------------------------------------
/spring-boot-kotlin/src/test/resources/application.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HotswapProjects/HotswapAgentExamples/6b313ca4e24087f5a05d46f63ddece51cf1e9418/spring-boot-kotlin/src/test/resources/application.yml
--------------------------------------------------------------------------------
/spring-boot/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | hotswap-agent-examples-aggregator
6 | org.hotswapagent
7 | 1.4.2-SNAPSHOT
8 |
9 |
10 | 4.0.0
11 |
12 | org.hotswapagent.example
13 | spring-boot
14 | 0.0.1-SNAPSHOT
15 | jar
16 |
17 | spring-boot
18 | Example project for Spring Boot
19 |
20 |
21 | UTF-8
22 | UTF-8
23 | 1.8
24 | 2.7.11
25 |
26 |
27 |
28 |
29 |
30 | org.springframework.boot
31 | spring-boot-dependencies
32 | ${spring.boot.version}
33 | pom
34 | import
35 |
36 |
37 |
38 |
39 |
40 |
41 | org.springframework.boot
42 | spring-boot-starter
43 |
44 |
45 |
46 | org.springframework.boot
47 | spring-boot-starter-web
48 |
49 |
50 |
51 | org.springframework.boot
52 | spring-boot-starter-webflux
53 |
54 |
55 |
56 | org.springframework.boot
57 | spring-boot-starter-test
58 | test
59 |
60 |
61 |
62 | org.hotswapagent
63 | hotswap-agent-spring-plugin
64 | 1.4.2-SNAPSHOT
65 | test
66 |
67 |
68 |
69 | junit
70 | junit
71 |
72 |
73 |
74 |
75 |
76 |
77 | org.springframework.boot
78 | spring-boot-maven-plugin
79 | ${spring.boot.version}
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/spring-boot/src/main/java/org/hotswap/agent/example/springboot/HotswapSpringBoot.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.springboot;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.context.annotation.ComponentScan;
6 | import org.springframework.context.annotation.FilterType;
7 |
8 | @SpringBootApplication
9 | @ComponentScan(excludeFilters={
10 | @ComponentScan.Filter(type= FilterType.REGEX, pattern=".*2$")})
11 | public class HotswapSpringBoot {
12 |
13 | public static void main(String[] args) {
14 | SpringApplication.run(HotswapSpringBoot.class, args);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/spring-boot/src/main/java/org/hotswap/agent/example/springboot/TestPojo.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.springboot;
2 |
3 | public class TestPojo {
4 | public int version() { return 0; }
5 | }
6 |
--------------------------------------------------------------------------------
/spring-boot/src/main/java/org/hotswap/agent/example/springboot/TestPojo2.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.springboot;
2 |
3 | public class TestPojo2 {
4 | public int version() { return 1; }
5 |
6 | public void test() {
7 |
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/spring-boot/src/main/java/org/hotswap/agent/example/springboot/TestRest.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.springboot;
2 |
3 | import org.springframework.web.bind.annotation.*;
4 |
5 | @RestController
6 | public class TestRest {
7 | @GetMapping(value = "/hello")
8 | @ResponseBody
9 | public String hello() {
10 | return "hello";
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/spring-boot/src/main/java/org/hotswap/agent/example/springboot/TestRest2.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.springboot;
2 |
3 | import org.springframework.web.bind.annotation.GetMapping;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.ResponseBody;
6 | import org.springframework.web.bind.annotation.RestController;
7 |
8 | @RestController
9 | public class TestRest2 {
10 | @GetMapping(value = "/hello2")
11 | @ResponseBody
12 | public String hello() {
13 | return "hello2";
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/spring-boot/src/main/resources/application.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HotswapProjects/HotswapAgentExamples/6b313ca4e24087f5a05d46f63ddece51cf1e9418/spring-boot/src/main/resources/application.properties
--------------------------------------------------------------------------------
/spring-boot/src/main/resources/hotswap-agent.properties:
--------------------------------------------------------------------------------
1 | LOGGER=debug
2 |
--------------------------------------------------------------------------------
/spring-boot/src/test/java/org/hotswap/agent/example/springboot/BasicSpringBootTest.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.springboot;
2 |
3 | import org.hotswap.agent.plugin.hotswapper.HotSwapper;
4 | import org.hotswap.agent.plugin.spring.scanner.ClassPathBeanDefinitionScannerAgent;
5 | import org.hotswap.agent.util.test.WaitHelper;
6 | import org.junit.Test;
7 | import org.junit.runner.RunWith;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.boot.test.context.SpringBootTest;
10 | import org.springframework.context.ApplicationContext;
11 | import org.springframework.test.context.junit4.SpringRunner;
12 |
13 | import static org.junit.Assert.assertEquals;
14 | import static org.junit.Assert.assertNotNull;
15 | import static org.junit.Assert.assertTrue;
16 |
17 | @RunWith(SpringRunner.class)
18 | @SpringBootTest
19 | public class BasicSpringBootTest {
20 | @Autowired
21 | ApplicationContext applicationContext;
22 |
23 | @Test
24 | public void contextLoads() {
25 | assertNotNull(applicationContext);
26 | }
27 |
28 | @Test
29 | public void addMethodDidNotChangeSpringBeanNames() throws Exception {
30 | TestPojo test = applicationContext.getAutowireCapableBeanFactory().createBean(TestPojo.class);
31 | assertEquals(0, applicationContext.getBeanNamesForType(TestPojo.class).length);
32 |
33 | swapClasses(TestPojo.class, TestPojo2.class);
34 |
35 |
36 | assertEquals(0, applicationContext.getBeanNamesForType(TestPojo.class).length);
37 | }
38 |
39 |
40 | public static void swapClasses(Class original, Class swap) throws Exception {
41 | ClassPathBeanDefinitionScannerAgent.reloadFlag = true;
42 | HotSwapper.swapClasses(original, swap.getName());
43 | assertTrue(WaitHelper.waitForCommand(new WaitHelper.Command() {
44 | @Override
45 | public boolean result() throws Exception {
46 | return !ClassPathBeanDefinitionScannerAgent.reloadFlag;
47 | }
48 | }));
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/spring-boot/src/test/java/org/hotswap/agent/example/springboot/RestTest.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.springboot;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.boot.test.context.SpringBootTest;
7 | import org.springframework.test.context.junit4.SpringRunner;
8 | import org.springframework.test.web.reactive.server.WebTestClient;
9 |
10 | import static org.hotswap.agent.example.springboot.BasicSpringBootTest.swapClasses;
11 |
12 | @RunWith(SpringRunner.class)
13 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
14 | public class RestTest {
15 | @Autowired
16 | private WebTestClient webClient;
17 |
18 | @Test
19 | public void exampleTest() throws Exception {
20 | this.webClient.get().uri("/hello").exchange().expectStatus().isOk()
21 | .expectBody(String.class).isEqualTo("hello");
22 |
23 | swapClasses(TestRest.class, TestRest2.class);
24 |
25 | this.webClient.get().uri("/hello").exchange().expectStatus().is4xxClientError();
26 |
27 | this.webClient.get().uri("/hello2").exchange().expectStatus().isOk()
28 | .expectBody(String.class).isEqualTo("hello2");
29 |
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/spring-hibernate/README.md:
--------------------------------------------------------------------------------
1 | Spring + Hibernate + Spring MVC
2 | ===============================
3 |
4 | Example of application setup with:
5 | * Spring 35.3.26
6 | * Hibernate Entity Manager 5.4.33
7 | * Spring WebMVC
8 |
9 | You need to specify java startup properties with dcevm and javaagent:
10 | java -javaagent:HotswapAgent.jar
11 |
12 | It is preconfigured with maven jetty plugin, run:
13 | * mvn clean package
14 | * mvn jetty:run
15 | * launch web browser on http://localhost:8080/
16 |
17 | The application is preconfigured for automatic hotswap deployment (see autoHotswap property in hotswap-agent.properties).
18 | If you specify java startup parameters, all changes to class file will be automatically reloaded:
19 | java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
20 | If you start the application in debug mode, autoHotswap will be disabled and you should use IDE hotswap feature instead.
21 |
22 | To enable debug of Hotswap reload on JVM level, add -Xlog:redefine+class*=debug java startup parameter:
23 | java -javaagent:..\HotswapAgent\target\HotswapAgent.jar -Xlog:redefine+class*=debug
24 |
--------------------------------------------------------------------------------
/spring-hibernate/runtime/data/agent-test.hsqldb.lck:
--------------------------------------------------------------------------------
1 | HSQLLOCK FQ2
H
--------------------------------------------------------------------------------
/spring-hibernate/runtime/data/agent-test.hsqldb.properties:
--------------------------------------------------------------------------------
1 | #HSQL Database Engine 2.2.8
2 | #Sat May 31 09:32:53 CEST 2014
3 | version=2.2.8
4 | modified=yes
5 |
--------------------------------------------------------------------------------
/spring-hibernate/src/main/java-extra/org/hotswap/agent/examples/plain/HelloWorld.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | /**
4 | * Hello world class.
5 | */
6 | public class HelloWorld {
7 | public static String hello() {
8 | return "Hello World Extra";
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/spring-hibernate/src/main/java-extra/org/hotswap/agent/examples/plain/HelloWorldHotswap.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example;
2 |
3 | /**
4 | * Hello world class to be replaced by hotswap.
5 | */
6 | public class HelloWorldHotswap {
7 | public static String hello() {
8 | return "Hello World Extra";
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/spring-hibernate/src/main/java-hotswap/org/hotswap/agent/examples/service/TestRepository.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.service;
2 |
3 | import org.springframework.stereotype.Repository;
4 |
5 | /**
6 | * Hello world repository to be replaced by hotswap
7 | */
8 | @Repository
9 | public class TestRepository {
10 | public String helloWorld() {
11 | return "Hello world Hotswap";
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/spring-hibernate/src/main/java/org/hotswap/agent/example/model/TestEntity.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.model;
2 |
3 | import javax.persistence.Entity;
4 | import javax.persistence.GeneratedValue;
5 | import javax.persistence.Id;
6 |
7 | /**
8 | * Test entity
9 | */
10 | @Entity
11 | public class TestEntity {
12 | @Id
13 | @GeneratedValue
14 | private Long id;
15 |
16 | private String name;
17 |
18 | //@Transient
19 | private String value;
20 |
21 | public TestEntity() {
22 | // Uncomment and reorder to test AnonymousClassPatchPlugin
23 | // new Exception() {};
24 | // new Serializable() {};
25 | // new Cloneable() {};
26 | }
27 |
28 | public TestEntity(String value) {
29 | }
30 |
31 |
32 | public Long getId() {
33 | return id;
34 | }
35 |
36 | public void setId(Long id) {
37 | this.id = id;
38 | }
39 |
40 | public String getValue() {
41 | return value;
42 | }
43 |
44 | public void setValue(String value) {
45 | this.value = value;
46 | }
47 |
48 | public String getName() {
49 | return name;
50 | }
51 |
52 | public void setName(String name) {
53 | this.name = name;
54 | }
55 |
56 | @Override
57 | public String toString() {
58 | return "TestEntity{" +
59 | "id=" + id +
60 | ", name='" + name + '\'' +
61 | ", value='" + value + '\'' +
62 | '}';
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/spring-hibernate/src/main/java/org/hotswap/agent/example/mvc/IndexController.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.mvc;
2 |
3 | import org.hotswap.agent.example.model.TestEntity;
4 | import org.hotswap.agent.example.service.TestEntityService;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.context.ApplicationContext;
7 | import org.springframework.stereotype.Controller;
8 | import org.springframework.ui.ModelMap;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 |
11 | import java.io.IOException;
12 | import java.io.InputStream;
13 | import java.io.Writer;
14 |
15 | /**
16 | * Simple Spring MVC controller.
17 | *
18 | * Note, that Spring MVC is not fully supported for reload (e.g. endpoint mapping).
19 | */
20 | @Controller
21 | @RequestMapping
22 | public class IndexController {
23 |
24 | @Autowired
25 | TestEntityService testEntityService;
26 |
27 | @Autowired
28 | ApplicationContext applicationContext;
29 |
30 | @RequestMapping("/hello")
31 | public void helloWorld(Writer writer) throws IOException {
32 | writer.write("Hello World");
33 | }
34 |
35 | @RequestMapping("/helloRepository")
36 | public void helloWorldRepository(Writer writer) throws IOException {
37 | // applicationContext.getBean instead of autowired service, because Spring MVC bean is sometimes
38 | // not reloaded - will be part of Spring MVC plugin
39 | writer.write(applicationContext.getBean(TestEntityService.class).helloWorld3());
40 | }
41 |
42 | /**
43 | * Experiment with entities and Hibernate.
44 | */
45 | @RequestMapping("/hibernate")
46 | public String printHello(ModelMap model) {
47 | TestEntity a = new TestEntity("Hello world");
48 | testEntityService.addTestEntity(a);
49 | model.addAttribute("entities", testEntityService.loadTestEntities());
50 | return "test";
51 | }
52 |
53 | /**
54 | * Check reload resource behaviour - before and after change,
55 | */
56 | @RequestMapping("/reloadResource")
57 | public void printHello(Writer writer) throws IOException {
58 | InputStream is = getClass().getResourceAsStream("/test.resource");
59 | java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
60 | writer.write(s.next());
61 | }
62 |
63 | }
--------------------------------------------------------------------------------
/spring-hibernate/src/main/java/org/hotswap/agent/example/service/TestEntityService.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.service;
2 |
3 | import org.hotswap.agent.example.model.TestEntity;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.stereotype.Service;
6 | import org.springframework.transaction.annotation.Transactional;
7 |
8 | import javax.persistence.EntityManager;
9 | import javax.persistence.PersistenceContext;
10 | import java.util.List;
11 |
12 | /**
13 | * Experiment with this service in debug mode to check Spring reloading.
14 | *
15 | * @author Jiri Bubnik
16 | */
17 | @Service
18 | @Transactional
19 | public class TestEntityService {
20 |
21 | @Autowired
22 | TestRepository testRepository;
23 |
24 | @PersistenceContext
25 | EntityManager entityManager;
26 |
27 |
28 | public void addTestEntity(TestEntity entity) {
29 | entityManager.persist(entity);
30 | }
31 |
32 | @SuppressWarnings("unchecked")
33 | public List loadTestEntities() {
34 | return entityManager.createQuery("select e from TestEntity e").getResultList();
35 | }
36 |
37 | public String helloWorld() {
38 | return "Hello World";
39 | }
40 |
41 | public String helloWorld3() {
42 | return "Hello World2";
43 | }
44 |
45 | // return text from repository and ExamplePlugin values.
46 | public String helloWorldRepository() {
47 | return testRepository.helloWorld();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/spring-hibernate/src/main/java/org/hotswap/agent/example/service/TestRepository.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.service;
2 |
3 | import org.springframework.stereotype.Repository;
4 |
5 | /**
6 | * Hello world repository.
7 | */
8 | @Repository
9 | public class TestRepository {
10 | public String helloWorld() {
11 | return "Hello world";
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/spring-hibernate/src/main/resources-extra/test.properties:
--------------------------------------------------------------------------------
1 | hello=Hello World Extra
--------------------------------------------------------------------------------
/spring-hibernate/src/main/resources-watch/testWatch.properties:
--------------------------------------------------------------------------------
1 | hello=This should never happen - before change contents should be read from target/classes.
--------------------------------------------------------------------------------
/spring-hibernate/src/main/resources-watch/testWatchReplace.properties:
--------------------------------------------------------------------------------
1 | hello=Hello World Watch
--------------------------------------------------------------------------------
/spring-hibernate/src/main/resources/META-INF/persistence.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | org.hibernate.ejb.HibernatePersistence
5 | jdbc/ToDoDB
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/spring-hibernate/src/main/resources/examplePlugin.resource:
--------------------------------------------------------------------------------
1 | Change this file and see the result in TestEntityService.helloWorld()
--------------------------------------------------------------------------------
/spring-hibernate/src/main/resources/hotswap-agent.properties:
--------------------------------------------------------------------------------
1 | watchResources=src/main/resources
2 | #J:/HotswapAgent/src/integration-test/resources
3 |
4 | # uncomment to test autohotswap feature
5 | #autoHotswap=true
6 |
7 | LOGGER.org.hotswap.agent=DEBUG
8 | #LOGGER.org.hotswap.agent.plugin=TRACE
9 | #LOGGER.org.hotswap.agent.watch=TRACE
10 | #LOGGER.org.hotswap.agent.command=TRACE
11 |
--------------------------------------------------------------------------------
/spring-hibernate/src/main/resources/test.resource:
--------------------------------------------------------------------------------
1 | This value should be replaced in target/classes, but not replaced in src/main/resources.
2 | Use this example to test watchResources configuration property. Before the file is changed, it loads
3 | value from target/classes and should replace the value with application name. After the file is changed,
4 | it is served from src/main/resources and it is not replaced.
5 |
6 | VALUE: '${name}'
--------------------------------------------------------------------------------
/spring-hibernate/src/main/webapp/META-INF/context.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/spring-hibernate/src/main/webapp/WEB-INF/AgentWeb-servlet.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/spring-hibernate/src/main/webapp/WEB-INF/jboss-web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | other
4 | /spring-hibernate
5 |
6 | jdbc/ToDoDB
7 | java:/jdbc/ToDoDB
8 | javax.sql.DataSource
9 |
10 |
11 |
--------------------------------------------------------------------------------
/spring-hibernate/src/main/webapp/WEB-INF/jetty-env.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | jdbc/ToDoDB
8 |
9 |
10 |
11 | jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
12 |
13 | sa
14 | sa
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/spring-hibernate/src/main/webapp/WEB-INF/jsp/test.jsp:
--------------------------------------------------------------------------------
1 | Hello World!
2 |
3 | ${entities}
--------------------------------------------------------------------------------
/spring-hibernate/src/main/webapp/WEB-INF/spring/applicationContext-jpa.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/spring-hibernate/src/main/webapp/WEB-INF/spring/applicationContext-service.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/spring-hibernate/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | DcevmAgent test
5 | DcevmAgent
6 |
7 |
8 |
9 | contextConfigLocation
10 | /WEB-INF/spring/*.xml
11 |
12 |
13 | org.springframework.web.context.ContextLoaderListener
14 |
15 |
16 |
17 |
18 | JpaFilter
19 | org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
20 |
21 |
22 | JpaFilter
23 | /*
24 |
25 |
26 | AgentWeb
27 | org.springframework.web.servlet.DispatcherServlet
28 | 1
29 |
30 |
31 |
32 | AgentWeb
33 | /mvc/*
34 |
35 |
36 |
37 |
38 | /index.jsp
39 |
40 |
41 |
42 |
43 | 120
44 |
45 |
46 |
47 |
48 | Database connection
49 | jdbc/ToDoDB
50 | javax.sql.DataSource
51 | Container
52 | Shareable
53 |
54 |
55 | persistence/TestPU
56 | TestPU
57 |
58 |
59 |
--------------------------------------------------------------------------------
/spring-hibernate/src/main/webapp/index.jsp:
--------------------------------------------------------------------------------
1 | Simple HotswapAgent test webapp
2 | Use this application as a "real world" test scenario.
3 |
4 | Read README.md for more information how to properly setup this application.
5 | Test pages:
6 |
--------------------------------------------------------------------------------
/spring-hibernate/src/test/java/org/hotswap/agent/example/mvc/IndexControllerIT.java:
--------------------------------------------------------------------------------
1 | package org.hotswap.agent.example.mvc;
2 |
3 | import org.apache.http.HttpResponse;
4 | import org.apache.http.HttpStatus;
5 | import org.apache.http.client.methods.HttpGet;
6 | import org.apache.http.client.methods.HttpUriRequest;
7 | import org.apache.http.impl.client.HttpClientBuilder;
8 | import org.apache.http.util.EntityUtils;
9 | import org.hotswap.agent.example.service.TestRepository;
10 | import org.hotswap.agent.util.test.WaitHelper;
11 | import org.junit.Test;
12 |
13 | import java.io.IOException;
14 | import java.nio.file.Files;
15 | import java.nio.file.Path;
16 | import java.nio.file.Paths;
17 | import java.nio.file.StandardCopyOption;
18 |
19 | import static org.junit.Assert.assertEquals;
20 |
21 | public class IndexControllerIT {
22 | String ENDPOINT = "http://localhost:8080/mvc/";
23 |
24 | @Test
25 | public void testUpAndRunning() throws Exception {
26 | HttpUriRequest request = new HttpGet(ENDPOINT + "hello");
27 |
28 | HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request);
29 | assertEquals(HttpStatus.SC_OK, httpResponse.getStatusLine().getStatusCode());
30 |
31 | assertEquals("Hello World", EntityUtils.toString(httpResponse.getEntity()));
32 | }
33 |
34 | @Test
35 | public void testHelloWord() throws IOException {
36 | final HttpUriRequest request = new HttpGet(ENDPOINT + "helloRepository");
37 |
38 | // replace the class file in extraClasspath (classloader looks into this directory)
39 | // autoHotswap should discover this change and reload the class
40 | String helloWorldFile = TestRepository.class.getName().replace(".", "/") + ".class";
41 | Path source = Paths.get("target/hotswap/" + helloWorldFile);
42 | Path target = Paths.get("target/classes/" + helloWorldFile);
43 | Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
44 |
45 | // wait for the hotswap
46 | boolean result = WaitHelper.waitForCommand(new WaitHelper.Command() {
47 | @Override
48 | public boolean result() throws Exception {
49 | HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request);
50 | return "Hello World Hotswap".equals(EntityUtils.toString(httpResponse.getEntity()));
51 | }
52 | });
53 | }
54 | }
--------------------------------------------------------------------------------