Hot re-deployment of a RESTlet - restlet

I'm interested in setting up a super lightweight web server with Restlet mostly for proofs-of-concept and low impedance collaboration with other developers. A full servlet container feels too heavy. Literally, I'm starting with something pulled directly from the "Getting Started" guide.
public class Dummy extends ServerResource {
public static void main(String[] args) throws Exception {
new Server(Protocol.HTTP, 8182, Dummy.class).start();
}
#Get("json")
public String hello() {
ST hello = new ST();
hello.add("name", "World");
return "{ \"hello\": \"World\"}";
}
}
However, I'd like to be able to watch for changes and redeploy automatically as I change code. I know Jetty can do this with some config. Has anyone done this without setting up a full servlet container? Is there something simpler?
I use Eclipse as my IDE to edit the code and launch the app, but the ideal solution wouldn't rely on that.

This what I call Continuous Delivery.
In a nutshell:
I usually use
SVN or Git to store and version source code
Jenkins to schedule the build and deployment
Gradle or Maven to build and test
The SCM plugin is able to poll the repository and invoke the process only if there is changes, or you can trigger the build with a hook.
There are plugins to copy your artifact to the target server and restart the application.

Related

IntelliJ run vs running a jar, with a Springboot Kotlin, Multi module Gradle project with Social Oauth2

TL;DR: Why does everything run fine when started via IntelliJ, and why is it broken when call java -jar app.jar. And how do I fix this?
Alright, I have some issues with a backend I am trying to dockerize. I have an application created with Spring Boot (1.4.2.RELEASE) following the Spring Oauth (2.0.12.RELEASE) guide on their page. I follow the Gradle version, since I prefer Gradle over Maven. Also I am using Kotlin instead of Java. Everything is fine, I start via IntelliJ my backend with static front end, I can login via Facebook (and Google and Github), I receive a nice Principal witch holds al the information I need, and I can modify Spring Security to authorize and permit endpoints. So far so good.
Now for the bad part, when I run either ./gradlew clean build app:bootrun or ./gradlew clean build app:jar and run the jar via java -jar (like I will do in my Docker container), my backend comes up. My static front end pops up. Now I want to login via Facebook, I end up on the Facebook login page, I enter my credentials, and... nothing!
I end up back on my homepage, not logged in, no log messages that mean anything to me, just silence. The last thing I see in the log is:Getting user info from: https://graph.facebook.com/me
This Url will give me in my browser:
{
"error": {
"message": "An active access token must be used to query information about the current user.",
"type": "OAuthException",
"code": 2500,
"fbtrace_id": "GV/58H5f4fJ"
}
}
When going to this URL via an IntelliJ start, it will give me credential details. Obviously something is going wrong, but I have no clue what. Especially since a run from IntelliJ works fine. There is some difference between how the jar is started, and how IntelliJ's run config works, but I have no clue where to search for what. I could post trace logging, or all my Gradle files, but perhaps thats too much info to put in 1 question. I will defenitly update this question if someone needs some more details :)
The structure outline of this project is as follows:
root:
- api: is going to be opensourced later, contains rest definitions and DTOs.
- core: contains the meat. Also here is included in the gradle file
spring-boot-starter, -web, -security, spring-security-oauth2, and some jackson stuff.
- rest: contains versioned rest service implementations.
- app: contains angular webjars amongst others, the front end, and
my `#SpringBootApplication`, `#EnableOAuth2Client`
and the impl of `WebSecurityConfigurerAdapter`.
Why does everything run fine when started via IntelliJ, and why is it broken using bootRun or the jar artefact. And how do I fix this?
I found it, the problem was not Multi module Graldle, Spring boot, or Oauth2 related. In fact it was due to a src set config of Gradle, where Java was supposed to be in a Java src set folder, and Kotlin in a Java src set folder:
sourceSets {
main.java.srcDirs += 'src/main/java'
main.kotlin.srcDirs += 'src/main/kotlin'
}
As Will Humphreys stated in his comment above, IntelliJ takes all source sets, and runs the app. However, when building the jar via Gradle, these source sets are stricter. I had a Java file in my Kotlin src set, which is no problem for IntelliJ. But the jar created by Gradle takes into account the source sets as defined in the build.gralde file, which are stricter.
I found my missing bean issue with the code below:
#Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
return args -> {
System.out.println("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
}
};
}
The Bean I missed was called AuthenticationController, which is a #RestController, and kinda crucial for my authentication code.

Error while running a simple GWTP Project in eclipse

`I'm new to gwtp and trying to learn it .I am trying to run a simple gwtp project on eclipse (Kepler) and my gwtp project contains a new presenter I have created under client package and i have only edited the UI.xml file just to check .But I dont seem to understand what the problem is ,as I'm trying to run the project in super dev mode Click here to see the console snap, i am getting this error :
Starting Jetty on port 8888
[WARN] FAILED guiceFilter: com.google.inject.ConfigurationException: Guice configuration errors:
1) No implementation for com.gwtplatform.dispatch.rpc.server.Dispatch was bound.
while locating com.gwtplatform.dispatch.rpc.server.Dispatch
for parameter 1 at com.gwtplatform.dispatch.rpc.server.guice.DispatchServiceImpl.(DispatchServiceImpl.java:54)
while locating com.gwtplatform.dispatch.rpc.server.guice.DispatchServiceImpl
2) No implementation for com.gwtplatform.dispatch.rpc.server.RequestProvider was bound.
while locating com.gwtplatform.dispatch.rpc.server.RequestProvider
for parameter 2 at com.gwtplatform.dispatch.rpc.server.guice.DispatchServiceImpl.(DispatchServiceImpl.java:54)
while locating com.gwtplatform.dispatch.rpc.server.guice.DispatchServiceImpl
You are most probably missing the installation of the GWTP needed modules.
Client Module file you need to install the GWTP modules (DefaultModule and RpcDispatchAsyncModule).
You should have something like:
public class ClientModule extends AbstractPresenterModule {
#Override
protected void configure() {
install(new DefaultModule());
install(new RpcDispatchAsyncModule()); // binds DispatchAsync to RpcDispatchAsync
install(new ApplicationModule()); //This is your main application module
// DefaultPlaceManager Places
bindConstant().annotatedWith(DefaultPlace.class).to(NameTokens.home);
bindConstant().annotatedWith(ErrorPlace.class).to(NameTokens.home);
bindConstant().annotatedWith(UnauthorizedPlace.class).to(NameTokens.home);
}
}

Use web project config.json when doing integration testing

I am using ASP.NET 5 RC1 and I need to write integration tests ...
So on the Test project, ASPNET5_WEB_TEST, I have the following:
public class IntegrationTests {
private readonly TestServer _server;
private readonly HttpClient _client;
public IntegrationTests() {
_server = new TestServer(TestServer.CreateBuilder().UseStartup<Startup>());
_client = _server.CreateClient();
}
// Test methods ...
}
The Startup class is from the ASP.NET 5 project I am testing: ASPNET5_WEB
When I run the test I get the following error:
The configuration file 'C:\Projects\ASPNET5_TEST\config.json' was not found and is not optional.
I know I get this error because on Startup I have:
builder
.AddJsonFile("config.json", false)
.AddJsonFile($"config.{environment.EnvironmentName}.json", true);
To fix this error I need to copy, at least, config.json from my web project, ASPNET5_WEB, to my test project, ASPNET5_WEB_TEST. But this means I will need to maintain duplicate config.json or at least copy it every time I make a change.
Can't I tell TestServer to use Startup of the web project and also its config.*.json files?
And can I have a config.testing.json and set on the TestServer the environment to Testing so the Startup code uses config.json and config.testing.json?
I assume you're using the TestServer from aspnet, if so, it wasn't built to support the way you're config files are read. The TestServer is used to run simple integration tests for their "hosting engine" but not for integrations tests for a website.
Their ApplicationDeployerFactory class is what you can use however. Refer to this as an example of how to run an "integration" server. I've used selenium in conjunction with that to run integration tests against the project I'm working on atm.
Yes, you can.
Take a look at this issue https://github.com/aspnet/Mvc/issues/3410 and The mentioned package.
Basically you need to implement your own IApplicationEnvironment

ClassNotFoundException on weblogic cluster node

We have a web application(.war) deployed on a weblogic 10.3.4 cluster in 'staging' mode.
So,the .war is copied over to the staging directory of the nodes;and the application is responding to user requests fine.
However,we get a ClassNotFoundException when a processor class tries to invoke an action class dynamically.
(Note: Processor and action have nothing to do with any of the frameworks.It is just a nomenclature.)
protected Action getAction(String sActionName) throws ActionException {
Action action = null;
Object o = null;
try {
String sClassName = getActionClassName(sActionName);
Class actionClass = Class.forName(sClassName);
o = actionClass.newInstance();
} catch(Exception e) {
}
return action;
}
We have verified that the class exists within the war and can be instantiated just fine through an independent application.
Why cant the node not find it then?
Do we need to point the application .war from the staging directory to weblogic classpath explicitly?
That would be quite odd.
You can try to check if your Classpath is correct using Weblogic CAT tool.
https://docs.oracle.com/cd/E24329_01/web.1211/e24368/classloading.htm#WLPRG495
CAT is a Web-based class analysis tool which simplifies filtering classloader configuration and aids you in analyzing classloading issues, such as detecting conflicts, debugging application classpaths and class conflicts, and proposes solutions to help you resolve them

Gradle jettyRun: how does this thing work?

Normally, I would start Jetty by constructing a Server instance, setting a connector, a handler, and LifeCycleListener, followed by a call to start() on the Server instance. I haven't the foggiest idea how to make this happen with the jettyRun task in Gradle. The documentation is confusing to me, and I have yet to find an example of how this task works, other than page after page of gradle jettyRun.
This task is appealing to me because it allegedly returns immediately after execution. This is helpful for running Selenium tests after my webapp is running from Jenkins. I tried to do this via a JavaExec task, but this won't work since the JavaExec task does not terminate until the underlying JVM terminates as well.
It sounds like you want to start Jetty for in-container integration tests. Besides having a look at the source code these two posts should get you started:
War and Jetty plugins with http integration tests
Right way to do basic web integration testing?
The key feature you are looking for, starting Jetty in the background, is jettyRun.daemon = true.
What I'm using for integration test in build.gradle is looks like below. I think this code is simple and intuitive.
test {
exclude '**/*IntegrationTest*'
}
task integrationTest(type: Test) {
include '**/*IntegrationTest*'
doFirst {
jettyRun.httpPort = 8080 // Port for test
jettyRun.daemon = true
jettyRun.execute()
}
doLast {
jettyStop.stopPort = 8091 // Port for stop signal
jettyStop.stopKey = 'stopKey'
jettyStop.execute()
}
}