I have a requirement to implement CustomSqlChange interface while my liquibase script runs. Following is my yaml changeSet entry:
changeSet:
customChange:
param:
_name: file
_value: "/com/example/data/user.csv"
_class: "com.example.MyClass"
id: id
author: abj
failOnError: true
Implementation for MyClass is as follows:
package com.example;
import liquibase.change.custom.CustomSqlChange;
import liquibase.change.custom.CustomSqlRollback;
import liquibase.database.Database;
import liquibase.exception.CustomChangeException;
import liquibase.exception.RollbackImpossibleException;
import liquibase.exception.SetupException;
import liquibase.exception.ValidationErrors;
import liquibase.resource.ResourceAccessor;
import liquibase.statement.SqlStatement;
public class MyClass implements CustomSqlChange, CustomSqlRollback {
//to hold the parameter value
private String file;
private ResourceAccessor resourceAccessor;
#Override
public String getConfirmationMessage() {
return "Confirmation Message from Custom SQL Change";
}
#Override
public void setUp() throws SetupException {
}
#Override
public void setFileOpener(ResourceAccessor resourceAccessor) {
this.resourceAccessor = resourceAccessor;
}
public String getFile() {
return file;
}
public void setFile(String file) {
this.file = file;
}
#Override
public ValidationErrors validate(Database database) {
return null;
}
#Override
public SqlStatement[] generateStatements(Database database) throws CustomChangeException {
return null;
}
#Override
public SqlStatement[] generateRollbackStatements(Database database)
throws CustomChangeException, RollbackImpossibleException {
return null;
}}
My Normal liquibase script runs successfully. I have a breakpoint in generateStatements method but the flow never comes to the breakpoint. Neither do any loggers are printed for the particular changeset at the time of application startup. Am I missing on to something?
Got it working with a slight change.
Implemented CustomTaskChange instead of CustomSqlChange.
Plus needed a parameter named changeId for some internal business logic.
The code is as follows:
yaml ChangeSet entry:
- changeSet:
id: id
author: abj
changes:
- customChange:
class: com.example.MyClass
params:
- param:
name: changeId
value: id
And Code for MyClass is:
package com.example;
import liquibase.change.custom.CustomTaskChange;
import liquibase.database.Database;
import liquibase.exception.CustomChangeException;
import liquibase.exception.SetupException;
import liquibase.exception.ValidationErrors;
import liquibase.resource.ResourceAccessor;
public class MyClass implements CustomTaskChange {
private String changeId;
public String getChangeId() {
return changeId;
}
public void setChangeId(String changeId) {
this.changeId = changeId;
}
#Override
public String getConfirmationMessage() {
return "Custom Task Change for "+this.getClass();
}
#Override
public void setUp() throws SetupException {
}
#Override
public void setFileOpener(ResourceAccessor resourceAccessor) {
}
#Override
public ValidationErrors validate(Database database) {
return null;
}
#Override
public void execute(Database database) throws CustomChangeException {
System.out.println("Code Flow comes Here");
}}
Related
I am trying to call the functions "beforeApprovingCCTransactions" and "afterApprovingCCTransactions" while "creditCardAmountBorrowedUpdation(..)" is triggered. The function is not getting triggered. Below is the snippet from XML.
File 1 :
package Logger;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
public class AuthorizeCCTransactionsLogs {
public void beforeApprovingCCTransactions() {
System.out.println("Going to begin transaction for Credit Card");
}
public void afterApprovingCCTransactions() {
System.out.println("Going to end transaction for Credit Card");
}
}
File 2:
package AuthorizeCCTransactions;
public class CreditCardHelper {
public void creditCardAmountBorrowedUpdation(CreditCardBean retievedCreditCardBean , double amount ) throws ClassNotFoundException {
retievedCreditCardBean.setAmount(retievedCreditCardBean.getAmount() + amount);
CreditCardTransactionsDao creditCardTransactionsDao = new CreditCardTransactionsDao();
creditCardTransactionsDao.update(retievedCreditCardBean);
}
}
Project Structure
XML File
When I create jetty websocket, I register my endpoint handler like this:
public class MyWebSocketEndpoint extends WebSocketServlet {
#Override
public void configure(WebSocketServletFactory webSocketServletFactory) {
webSocketServletFactory.register(MyEndpointHandler.class);
}
}
for MyEndpoingHandler class, I can't define a constructor with some parameters, or it will got runtime exception. How can I pass some parameters when create the MyEndpointHandler instance?
Use a WebSocketCreator.
When you call WebSocketServletFactory.register(MyEndpoingHandler.class) all that's happening internally is the equivalent of ...
#Override
public void register(Class<?> websocketPojo)
{
this.setCreator(new SingleEndpointCreator(websocketPojo));
}
Complete example on WebSocketCreator:
package websocket;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
public class DemoWebSocketCreator
{
public static class MyWebSocketServlet extends WebSocketServlet
{
#Override
public void configure(WebSocketServletFactory wsFactory)
{
wsFactory.setCreator(new MyWebSocketCreator());
}
}
public static class MyWebSocketCreator implements WebSocketCreator
{
private AtomicInteger idGen = new AtomicInteger(0);
#Override
public Object createWebSocket(ServletUpgradeRequest servletUpgradeRequest, ServletUpgradeResponse servletUpgradeResponse)
{
String id = "ws" + idGen.incrementAndGet();
return new MyWebSocket(id);
}
}
#WebSocket
public static class MyWebSocket
{
private final String id;
public MyWebSocket(String id)
{
this.id = id;
}
#OnWebSocketMessage
public void onMessage(Session session, String msg)
{
try
{
session.getRemote().sendString("Hello, my id is [" + id + "]: You said: " + msg);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception
{
Server server = new Server(8080);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
context.addServlet(MyWebSocketServlet.class, "/ws/");
// always last, and on default pathspec
context.addServlet(DefaultServlet.class, "");
HandlerList handlers = new HandlerList();
handlers.addHandler(context);
handlers.addHandler(new DefaultHandler());
server.setHandler(handlers);
server.start();
server.join();
}
}
I am able to use REDIS and RABBITMQ services which is on pivotal.While binding services I am able to get the Credentials and using that credentials in my application.properties for spring boot project.
But this configuration that I am using is hard-coded in application.Properties
To Make this configuration dynamically I came to know that we can use vcap services provided by pivotal.
So want to use run-time credentials for redis and rabbimq.
My Code is below for reference.
application.propeties
rabbitmq.host=hostname
rabbitmq.virtual-host=vhostanme
rabbitmq.username=username
rabbitmq.password=password
rabbit.mainqueue=abhi
rabbit.errorqueue=abc
redis.host=redishostname
redis.port=port
redis.password=password
My Config class:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
#Component
public class Config {
static String rabbitMqHost;
static String rabbitMqVHost;
static String rabbitMqUsername;
static String rabbitMqPassword;
static String rabbitMqMainQueue;
static String rabbitMqErrorQueue;
static String redisHost;
static int redisPort;
static String redisPassword;
Config() {
}
public static String getRedisHost() {
return redisHost;
}
public static void setRedisHost(String redisHost) {
Config.redisHost = redisHost;
}
public static int getRedisPort() {
return redisPort;
}
public static void setRedisPort(int redisPort) {
Config.redisPort = redisPort;
}
public static String getRedisPassword() {
return redisPassword;
}
public static void setRedisPassword(String redisPassword) {
Config.redisPassword = redisPassword;
}
public static String getRabbitMqMainQueue() {
return rabbitMqMainQueue;
}
public static void setRabbitMqMainQueue(String rabbitMqMainQueue) {
Config.rabbitMqMainQueue = rabbitMqMainQueue;
}
public static String getRabbitMqErrorQueue() {
return rabbitMqErrorQueue;
}
public static void setRabbitMqErrorQueue(String rabbitMqErrorQueue) {
Config.rabbitMqErrorQueue = rabbitMqErrorQueue;
}
public static String getRabbitMqHost() {
return rabbitMqHost;
}
public static void setRabbitMqHost(String rabbitMqHost) {
Config.rabbitMqHost = rabbitMqHost;
}
public static String getRabbitMqVHost() {
return rabbitMqVHost;
}
public static void setRabbitMqVHost(String rabbitMqVHost) {
Config.rabbitMqVHost = rabbitMqVHost;
}
public static String getRabbitMqUsername() {
return rabbitMqUsername;
}
public static void setRabbitMqUsername(String rabbitMqUsername) {
Config.rabbitMqUsername = rabbitMqUsername;
}
public static String getRabbitMqPassword() {
return rabbitMqPassword;
}
public static void setRabbitMqPassword(String rabbitMqPassword) {
Config.rabbitMqPassword = rabbitMqPassword;
}
#Value("${rabbitmq.host}")
public void setRabbitMqHosts(String url) {
setRabbitMqHost(url);
}
#Value("${rabbitmq.virtual-host}")
public void setRabbitMqVHosts(String url) {
setRabbitMqVHost(url);
}
#Value("${rabbitmq.username}")
public void setRabbitUsernames(String url) {
setRabbitMqUsername(url);
}
#Value("${rabbitmq.password}")
public void setRabbitPasswords(String url) {
setRabbitMqPassword(url);
}
#Value("${rabbit.mainqueue}")
public void setRabbitMainQueues(String url) {
setRabbitMqMainQueue(url);
}
#Value("${rabbit.errorqueue}")
public void setRabbitErrorQueues(String url) {
setRabbitMqErrorQueue(url);
}
#Value("${redis.host}")
public void setRedisHosts(String url) {
setRedisHost(url);
}
#Value("${redis.port}")
public void setRedisPorts(int url) {
setRedisPort(url);
}
#Value("${redis.password}")
public void setRedisPasswords(String url) {
setRedisPassword(url);
}
}
My MessagesConsumer class in which I am using that Conguration to take message from rabbitmq jms queue and save to redis:
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.jms.ConnectionFactory;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.es.consumer.config.Config;
import com.rabbitmq.jms.admin.RMQConnectionFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisShardInfo;
#Component
public class MessagesConsumer {
#Autowired
JmsTemplate jmsTemplate;
final Logger logger = LoggerFactory.getLogger(MessagesConsumer.class);
Jedis jedis;
JedisShardInfo shardInfo;
#PostConstruct
public void init() {
shardInfo = new JedisShardInfo(Config.getRedisHost(), Config.getRedisPort());
shardInfo.setPassword(Config.getRedisPassword());
jedis = new Jedis(shardInfo);
jedis.connect();
jedis.select(2);
}
#Bean
ConnectionFactory connectionFactory() {
RMQConnectionFactory connectionFactory = new RMQConnectionFactory();
connectionFactory.setUsername(Config.getRabbitMqUsername());
connectionFactory.setPassword(Config.getRabbitMqPassword());
connectionFactory.setVirtualHost(Config.getRabbitMqVHost());
connectionFactory.setHost(Config.getRabbitMqHost());
return connectionFactory;
}
#SuppressWarnings("rawtypes")
#Scheduled(fixedRate = 1)
public void readQueueAndSaveData() {
// take message process it and save to redis as hmset
}}
Any Help would be appreciable.
There are two ways of doing this.
1) Remove all the properties from application.properties, and write a configuration bean that will create RedisTemplate and RabbitTemplate beans for you. The factory properties required for these are to be obtained from the VCAP_SERVICES. On CF, the VCAP_SERVICES env variable, will have the services information that are binded to the app. When u push the app, with redis, rabbit service binded into your space, then their properties are available in VCAP_SERVICES. So just do System.getEnv("VCAP_SERVICES") in your code and then parse the json to get the service details to create the templates.
2) Remove the properties from application.properties, and use spring cloud connector. Spring cloud has a subproject called Spring cloud connectors that provide utilities to connect to various cloud services.
http://cloud.spring.io/spring-cloud-connectors/spring-cloud-spring-service-connector.html#_rabbitmq
Just you need to define a class that extends AbstractCloudConfig as below
class CloudConfig extends AbstractCloudConfig {
#Bean
public RabbitConnectionFactory rabbitFactory() {
return connectionFactory().rabbitConnectionFactory("rabbit-servicename");
}
#Bean
public RedisConnectionFactory redisFactory() {
return connectionFactory().redisConnectionFactory("redis-servicename");
}
}
The second approach is prefered if you are using Spring, as this needs very less coding and can be switched, to different cloud providers with no much effort.
I use:
Gwt-platform
Gwt Validation
Gwt UiEditor framework
Gwt Material inputs
After constraints validation I would like to display error messages. This is supported by gwt material inputs, like MaterialTextBox using method:  materialTextBox.setError("Please provide your name");
The problem is that it can be only executed from view class:
public class LoginView extends ViewWithUiHandlers<LoginUiHandlers> implements LoginPresenter.MyView {
interface Binder extends UiBinder<Widget, LoginView> {}
/** The driver to link the proxy bean with the view. */
public interface EditorDriver extends SimpleBeanEditorDriver<LoginModel, LoginView> { }
#UiField MaterialTextBox email;
#UiField MaterialTextBox password;
#UiField MaterialButton loginButton;
#UiField MaterialCheckBox keepMeLoggedInCheckbox;
#Inject
LoginView(Binder uiBinder) {
initWidget(uiBinder.createAndBindUi(this));
addClickHandlerToLoginButton();
}
//#UiHandler("loginButton")
private void onLoginButtonClick(ClickEvent e){
getUiHandlers().onLoginButtonClick();
}
private void addClickHandlerToLoginButton() {
loginButton.addClickHandler(new ClickHandler() {
#Override public void onClick(ClickEvent event) {
onLoginButtonClick(event);
}
});
}
#Override
public SimpleBeanEditorDriver<LoginModel, ?> createEditorDriver() {
EditorDriver driver = GWT.create(EditorDriver.class);
driver.initialize(this);
return driver;
}
public void test() {}
}
But I do all my editor/validation action in Presenter, and I do not have there any View connection I could use:
public class LoginPresenter extends Presenter<LoginPresenter.MyView, LoginPresenter.MyProxy> implements LoginUiHandlers {
public interface MyView extends BeanEditView<LoginModel>, HasUiHandlers<LoginUiHandlers> {}
public static final Type<RevealContentHandler<?>> SLOT_Login = new Type<RevealContentHandler<?>>();
#ProxyStandard
#NameToken(NameTokens.login)
public interface MyProxy extends ProxyPlace<LoginPresenter> {}
// Editor
private SimpleBeanEditorDriver<LoginModel, ?> editorDriver;
private static final LoginService service = GWT.create(LoginService.class);
private LoginModel model = new LoginModel("","");
#Override
public void onLoginButtonClick() {
if (editorDriver.isDirty()) {
model = editorDriver.flush();
validateModel();
if (editorDriver.hasErrors()) {
MaterialToast.fireToast("Errors occur");
StringBuilder errorBuilder = new StringBuilder();
for (EditorError error : editorDriver.getErrors()) {
errorBuilder.append(error.getMessage() + "\n");
}
MaterialToast.fireToast(errorBuilder.toString());
} else {
service.login(
model, new MethodCallback<Integer>() {
#Override
public void onSuccess(Method method, Integer response) {
MaterialToast.fireToast("Succefully set info. status code: " + response);
}
#Override
public void onFailure(Method method, Throwable exception) {
MaterialToast.fireToast("Error setting");
}
});
}
} else {
MaterialToast.fireToast("Data has not changed");
}
}
private void validateModel() {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<LoginModel>> violations = validator.validate(model);
if (violations.size() > 0) {
editorDriver.setConstraintViolations(new ArrayList<ConstraintViolation<?>>(violations));
}
}
#Inject
LoginPresenter(EventBus eventBus,MyView view, MyProxy proxy) {
super(eventBus, view, proxy, RevealType.Root);
getView().setUiHandlers(this);
editorDriver = getView().createEditorDriver();
editorDriver.edit(model);
}
}
I think that I should add an interface where I will declare methods to access inputs in view. And do implementation of that. But I don't know how. Please help me.
I've make it working. But really I am not quite sure what did happened that it start to work. So I will just share my working code:
Presenter
package pl.korbeldaniel.cms.client.login;
import java.util.ArrayList;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.fusesource.restygwt.client.Method;
import org.fusesource.restygwt.client.MethodCallback;
import gwt.material.design.client.ui.MaterialToast;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.editor.client.SimpleBeanEditorDriver;
import com.google.gwt.event.shared.GwtEvent.Type;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.annotations.ProxyStandard;
import com.gwtplatform.mvp.client.proxy.ProxyPlace;
import com.gwtplatform.mvp.client.annotations.NameToken;
import com.gwtplatform.mvp.client.proxy.RevealContentHandler;
import com.gwtplatform.mvp.client.HasUiHandlers;
import pl.korbeldaniel.cms.client.editor.BeanEditView;
import pl.korbeldaniel.cms.client.model.LoginModel;
import pl.korbeldaniel.cms.client.place.NameTokens;
import pl.korbeldaniel.cms.client.service.LoginService;
public class LoginPresenter extends Presenter<LoginPresenter.MyView, LoginPresenter.MyProxy> implements LoginUiHandlers {
#ProxyStandard
#NameToken(NameTokens.login)
public interface MyProxy extends ProxyPlace<LoginPresenter> {}
public interface MyView extends BeanEditView<LoginModel>, HasUiHandlers<LoginUiHandlers> {}
public static final Type<RevealContentHandler<?>> SLOT_Login = new Type<RevealContentHandler<?>>();
// Editor
private SimpleBeanEditorDriver<LoginModel, ?> editorDriver;
private static final LoginService service = GWT.create(LoginService.class);
private LoginModel model = new LoginModel();
#Override
public void onLoginButtonClick() {
if (editorDriver.isDirty()) {
model = editorDriver.flush();
validateModel();
if (editorDriver.hasErrors()) {
MaterialToast.fireToast("Errors occur");
} else {
service.login(
model, new MethodCallback<Integer>() {
#Override
public void onSuccess(Method method, Integer response) {
MaterialToast.fireToast("Succefully set info. status code: " + response);
}
#Override
public void onFailure(Method method, Throwable exception) {
MaterialToast.fireToast("Error setting");
}
});
}
} else {
MaterialToast.fireToast("Data has not changed");
}
}
private void validateModel() {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<LoginModel>> violations = validator.validate(model);
GWT.log(String.valueOf(violations.size()));
if (violations.size() > 0) {
editorDriver.setConstraintViolations(new ArrayList<ConstraintViolation<?>>(violations));
}
model.validate();
}
#Inject
LoginPresenter(EventBus eventBus,MyView view, MyProxy proxy) {
super(eventBus, view, proxy, RevealType.Root);
getView().setUiHandlers(this);
editorDriver = getView().createEditorDriver();
editorDriver.edit(model);
}
public enum EditorMode {
VIEW, EDIT, CREATE
};
}
Ui Handler
package pl.korbeldaniel.cms.client.login;
import com.gwtplatform.mvp.client.UiHandlers;
interface LoginUiHandlers extends UiHandlers {
void onLoginButtonClick();
}
ValidatorFactory
package pl.korbeldaniel.cms.client.login;
import javax.validation.Validator;
import pl.korbeldaniel.cms.client.model.LoginModel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.validation.client.AbstractGwtValidatorFactory;
import com.google.gwt.validation.client.GwtValidation;
import com.google.gwt.validation.client.impl.AbstractGwtValidator;
public final class SampleValidatorFactory extends AbstractGwtValidatorFactory {
/**
* Validator marker for the Validation Sample project. Only the classes and
* groups listed in the {#link GwtValidation} annotation can be validated.
*/
#GwtValidation(LoginModel.class)
public interface GwtValidator extends Validator {
}
#Override
public AbstractGwtValidator createValidator() {
return GWT.create(GwtValidator.class);
}
}
View
package pl.korbeldaniel.cms.client.login;
import gwt.material.design.client.ui.MaterialButton;
import gwt.material.design.client.ui.MaterialCheckBox;
import gwt.material.design.client.ui.MaterialTextBox;
import javax.inject.Inject;
import pl.korbeldaniel.cms.client.model.LoginModel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.editor.client.SimpleBeanEditorDriver;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Widget;
import com.gwtplatform.mvp.client.ViewWithUiHandlers;
public class LoginView extends ViewWithUiHandlers<LoginUiHandlers> implements LoginPresenter.MyView {
interface Binder extends UiBinder<Widget, LoginView> {}
/** The driver to link the proxy bean with the view. */
public interface EditorDriver extends SimpleBeanEditorDriver<LoginModel, LoginView> { }
#UiField MaterialTextBox email;
#UiField MaterialTextBox password;
#UiField MaterialButton loginButton;
#UiField MaterialCheckBox keepMeLoggedInCheckbox;
#Inject
LoginView(Binder uiBinder) {
initWidget(uiBinder.createAndBindUi(this));
addClickHandlerToLoginButton();
}
//#UiHandler("loginButton")
private void onLoginButtonClick(ClickEvent e){
getUiHandlers().onLoginButtonClick();
}
private void addClickHandlerToLoginButton() {
loginButton.addClickHandler(new ClickHandler() {
#Override public void onClick(ClickEvent event) {
onLoginButtonClick(event);
}
});
}
#Override
public SimpleBeanEditorDriver<LoginModel, ?> createEditorDriver() {
EditorDriver driver = GWT.create(EditorDriver.class);
driver.initialize(this);
return driver;
}
}
View Binder
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:m="urn:import:gwt.material.design.client.ui"
xmlns:e="urn:import:pl.korbeldaniel.cms.client.login">
<m:MaterialRow ui:field="loginWidget">
<m:MaterialColumn grid="s12 m4 l4" offset="l4 m4" >
<m:MaterialTitle title="Login" description="Please provide your account credentials."/>
<m:MaterialPanel padding="5" shadow="1" addStyleNames="{style.panel}">
<m:MaterialPanel addStyleNames="{style.fieldPanel}">
<!-- <m:MaterialImage url="http://b.vimeocdn.com/ps/339/488/3394886_300.jpg" type="CIRCLE" addStyleNames="{style.imgProfile} z-depth-1"/> -->
<m:MaterialTextBox ui:field="email" type="EMAIL" placeholder="Email"/>
<m:MaterialTextBox ui:field="password" type="PASSWORD" placeholder="Password"/>
<m:MaterialRow addStyleNames="{style.rowAction}">
<m:MaterialColumn grid="s12 m12 l6">
<m:MaterialCheckBox ui:field="keepMeLoggedInCheckbox" text="Keep me logged in"/>
</m:MaterialColumn>
</m:MaterialRow>
<m:MaterialButton ui:field="loginButton" waves="LIGHT" text="Log In" width="100%"/>
</m:MaterialPanel>
</m:MaterialPanel>
</m:MaterialColumn>
</m:MaterialRow>
</ui:UiBinder>
I am trying to do an Jetty Web Socket example .
I copied a example from internet , which was working fine when i deployed directly into server without making any chnages .
But when i copied the Source (the servlet) into Eclipse IDE , it was giving Compilation
Exceptions related to
The method onClose(int, String) of type Html5Servlet.StockTickerSocket must override a superclass method
- The method onOpen(WebSocket.Connection) of type Html5Servlet.StockTickerSocket must override a superclass method
The method onMessage(String) of type Html5Servlet.StockTickerSocket must override a superclass method
This is my servlet , i kept the jars as it is mentioned in that example
package org.ajeesh.app;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketServlet;
public class Html5Servlet extends WebSocketServlet {
private AtomicInteger index = new AtomicInteger();
private static final List<String> tickers = new ArrayList<String>();
static{
tickers.add("ajeesh");
tickers.add("peeyu");
tickers.add("kidillan");
tickers.add("entammo");
}
/**
*
*/
private static final long serialVersionUID = 1L;
public WebSocket doWebSocketConnect(HttpServletRequest req, String resp) {
System.out.println("On server");
return new StockTickerSocket();
}
protected String getMyJsonTicker(){
StringBuilder start=new StringBuilder("{");
start.append("\"stocks\":[");
int counter=0;
for (String aTicker : tickers) {
counter++;
start.append("{ \"ticker\":\""+aTicker +"\""+","+"\"price\":\""+index.incrementAndGet()+"\" }");
if(counter<tickers.size()){
start.append(",");
}
}
start.append("]");
start.append("}");
return start.toString();
}
public class StockTickerSocket implements WebSocket.OnTextMessage{
private Connection connection;
private Timer timer;
#Override
public void onClose(int arg0, String arg1) {
System.out.println("Web socket closed!");
}
#Override
public void onOpen(Connection connection) {
System.out.println("onOpen!");
this.connection=connection;
this.timer=new Timer();
}
#Override
public void onMessage(String data) {
System.out.println("onMessage!");
if(data.indexOf("disconnect")>=0){
connection.close();
timer.cancel();
}else{
sendMessage();
}
}
private void sendMessage() {
System.out.println("sendMessage!");
if(connection==null||!connection.isOpen()){
System.out.println("Connection is closed!!");
return;
}
timer.schedule(new TimerTask() {
#Override
public void run() {
try{
System.out.println("Running task");
connection.sendMessage(getMyJsonTicker());
}
catch (IOException e) {
e.printStackTrace();
}
}
}, new Date(),5000);
}
}
}