I'm working on a GWT project and have several void remote services that seem to execute just fine, but on the client side, end up firing the onFailure() method. No exceptions are thrown anywhere, and the expected behavior is observed on the backend. I have no idea what could be going wrong. Here is the relevant code:
Interfaces and implementation...
#RemoteServiceRelativePath("DeleteSearchService")
public interface DeleteSearchService extends RemoteService {
/**
* Utility class for simplifying access to the instance of async service.
*/
public static class Util {
private static DeleteSearchServiceAsync instance;
public static DeleteSearchServiceAsync getInstance(){
if (instance == null) {
instance = GWT.create(DeleteSearchService.class);
}
return instance;
}
}
public void delete(SearchBean search);
}
public interface DeleteSearchServiceAsync {
public void delete(SearchBean bean, AsyncCallback<Void> callback);
}
public class DeleteSearchServiceImpl extends RemoteServiceServlet implements DeleteSearchService {
private static final long serialVersionUID = 1L;
#Override
public void delete(SearchBean search) {
try {
Connection conn = SQLAccess.getConnection();
String sql = "DELETE FROM `searches` WHERE `id`=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, search.getSearchId());
ps.execute();
sql = "DELETE FROM `searchsourcemap` WHERE `search-id` = ?";
ps = conn.prepareStatement(sql);
ps.setInt(1, search.getSearchId());
ps.execute();
return;
} catch (Exception e) {
// TODO Log error
e.printStackTrace();
}
}
}
Calling code...
private class DeleteListener implements ClickListener {
public void onClick(Widget sender) {
DeleteSearchServiceAsync dss = DeleteSearchService.Util.getInstance();
SearchBean bean = buildBeanFromGUI();
dss.delete(bean, new AsyncCallback<Void>(){
//#Override
public void onFailure(Throwable caught) {
// TODO log
SearchNotDeleted snd = new SearchNotDeleted();
snd.show();
}
//#Override
public void onSuccess(Void result) {
SearchDeleted sd = new SearchDeleted();
sd.show();
searchDef.getParent().removeFromParent();
}
});
}
}
I know I'm a jerk for posting like 500 lines of code but I've been staring at this since yesterday and can't figure out where I'm going wrong. Maybe a 2nd set of eyes would help...
Thanks,
brian
LGTM I'm afraid.
Are you using the hosted mode or a full-fledged browser? You can try switching and see if it helps.
Also, it might help listening to that //TODO and perform a GWT.log when onFailure is invoked.
Related
I'm trying to migrate from EJB2.x to EJB3.x and i'm using Wildfly 9.0.0.
The old EJB2.x is working in JBoss 4.2.2 and this is how it looks like:
public interface WUFFacadeRemote extends EJBObject {
public ClientData getItems(ClientData data);
public ClientData save(ClientData data);
}
public interface WUFFacadeHome extends EJBHome {
public WUFFacadeRemote create();
}
public class WUFFacade {
public ClientData getItems(ClientData data) {
//code here
}
public ClientData save(ClientData data) {
//code here
}
}
public class WUFAction extends HttpServlet implements IAction {
public void doPost(HttpServletRequest request, HttpServletResponse response) {
...
Object objRef = ic.lookup("java:comp/env/wUF");
com.wuf.WUFFacadeHome home = (com.wuf.WUFFacadeHome) PortableRemoteObject.narrow(objRef, com.wuf.WUFFacadeHome.class);
engine = home.create();
//engine gets the reference, and I can use it normally.
...
}
}
I also have the ejb-jar.xml and it's working. Now, the solution I was thinking to EJB3.x and Wildfly 9.0.0 is as below:
#WebServlet(urlPatterns = "windows/wUF.do", loadOnStartup = 1)
public class WUFAction extends HttpServlet implements IAction {
#EJB
private WUFFacadeRemote engine;
public void doPost(HttpServletRequest request, HttpServletResponse response) {
//Here I should be able to use my engine.
//Wildfly starts and I call the page, engine is not null at this moment,
//but after I call the page again, it becomes null and remains null.
}
}
#Stateless
#Remote(WUFFacadeRemote.class)
public class WUFFacade extends RootFacade implements WUFFacadeRemote, Serializable {
public WUFFacade() { }
#EJB
FUFHome home;
public ClientData getItems(ClientData data) {
//code here
}
public ClientData save(ClientData data) {
//code here
}
private Col load(ClientData data,InitialContext ic) {
//here i'm calling home.
// but home is always null. It was supposed to have the #EJB reference initialized.
//But instead I get a null pointer...
home.findByFilter(loader);
}
}
#Remote(FUFHome.class)
public interface FUFHome {
FUF create(FUFValue fUFValue);
FUF findByPrimaryKey(FUFPK pk);
Collection findByFilter(FacadeLoader loader);
}
public interface WUFFacadeRemote{
public ClientData getItems(ClientData data);
public ClientData save(ClientData data);
}
I don't have ejb-jar.xml anymore, the deploy is sucessfully done and Wildfly starts with no errors. Then the first time I call the page in question, it seems that #EJB is working (Debug is "Proxy for remote EJB StatelessEJBLocator for "bus-facade/WUFFacade", view is interface com.wuf.WUFFacadeRemote, affinity is None"), the value is not null, but for all subsequent calls, my variable is null and I got a NullPointerException.
I really don't know what i'm doing wrong (maybe i'm completely lost), but to me, #EJB should be working correctly like that. What am I missing? Thanks.
As i'm using EJB3.x i'm just using annotations now, (this seems to be ok).
JNDIs:
JNDI bindings for session bean named FUF in deployment
java:global/fumo/bus-entities-fumo/FUF!apyon.components.fumo.fuf.FUF
java:app/bus-entities-fumo/FUF!apyon.components.fumo.fuf.FUF
java:module/FUF!apyon.components.fumo.fuf.FUF
java:global/fumo/bus-entities-fumo/FUF
java:app/bus-entities-fumo/FUF
java:module/FUF
JNDI bindings for session bean named WUFFacade
java:global/fumo/bus-facade-fumo/WUFFacade!apyon.fumo.wuf.WUFFacadeRemote
java:app/bus-facade-fumo/WUFFacade!apyon.fumo.wuf.WUFFacadeRemote
java:module/WUFFacade!apyon.fumo.wuf.WUFFacadeRemote
java:jboss/exported/fumo/bus-facade-fumo/WUFFacade!apyon.fumo.wuf.WUFFacadeRemote
java:global/fumo/bus-facade-fumo/WUFFacade
java:app/bus-facade-fumo/WUFFacade
java:module/WUFFacade
I think I found a possible solution to the problem. I'll still try to find another one, but this is good so far.
After changing to a .war and keeping my other projects in .ears it's working. Maybe the problem was because I have a RootController servlet im my main.ear, which is the starting point of the aplication. The context starts there and then it redirects to fumo.ear (now fumo.war).
For some reason, I always was getting a null in my EJB after entering a page. It was always hapening when I first entered a JSP and tried to call the page again. My solution to this is:
#WebServlet(urlPatterns = "windows/wUF.do", loadOnStartup = 1)
public class WUFAction extends HttpServlet {
private WUFFacadeRemote engine;
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
doPost(req, resp);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) {
if(engine == null) {
InitialContext ic;
try {
ic = new InitialContext();
engine = (WUFFacadeRemote) ic.lookup("java:global/fumo/WUFFacade!fumo.wuf.WUFFacadeRemote");
} catch (NamingException e) {
e.printStackTrace();
}
}
//here I always have the context now.
}
}
And as a .war my structure now looks like this:
So other annotations like #Inject and #EJB are now working. Always when i'm being redirect from a JSP calling a Servlet or some action, I first check if the context is not null, otherwise I lookup it. My #Stateless are working and the #PersistenceContext and #Remote are working too.
#Stateless
public class WUFFacade implements WUFFacadeRemote {
#Inject
private FUFRules rules;
#EJB
private FUFHome home;
private Col load(ClientData data, InitialContext ic) throws InterfaceException {
try {
// home here is nor null anymore.
Collection res = (Collection) home.findByFilter(loader);
...
} catch (InterfaceException e) {
e.printStackTrace();
}
...
return data;
}
}
So I'd like to thank everyone who helped in the thread. It was a good way to understand and see the problem or to find a workaround. As I said, I'll still try the .ear in the future, but as a simplified packaging it definitely works.
I am relatively new to the Spring boot frame work. I had a basic web application built in Angular with Spring boot connected and to a Mongodb. The application allowed users to add todo lists and register for the the website. When the application started it returned the todolists stored in mongodb to the view. The user could register, and there details were stored in a Mongo repository.
When I added and implemented spring security I got the error message
Circular view path [login]: would dispatch back to the current handler URL [/login] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
What I want to happen is, when the webapp loads, I want the index.html to be injected with todo.html. Then if a user logs in they will be directed to another page or some Ui feature to become available. At the moment I am stuck in this Circular view pathloop.
I have looked through the different answers but I still am confused as to what exactly is causing the issue. I believe it is in the WebSecurityConfig class
#Configuration
#EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
#Autowired
UserDetailsService userDS;
#Override
protected void configure(HttpSecurity http) throws Exception{
http
.authorizeRequests()
.antMatchers("/api/todos/*").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDS);
}
#Override
protected UserDetailsService userDetailsService() {
return userDS;
}
}
AuthUserDetailsService
#Repository
public class AuthUserDetailsService implements UserDetailsService {
#Autowired
private UserRepository users;
private org.springframework.security.core.userdetails.User userdetails;
#Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
// TODO Auto-generated method stub
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
todoapp.models.User user = getUserDetail(username);
userdetails = new User (user.getUsername(),
user.getPassword(),
enabled,
accountNonExpired,
credentialsNonExpired,
accountNonLocked,
getAuthorities(user.getRole())
);
return userdetails;
}
public List<GrantedAuthority> getAuthorities(Integer role) {
List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
if (role.intValue() == 1) {
authList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
} else if (role.intValue() == 2) {
authList.add(new SimpleGrantedAuthority("ROLE_USER"));
}
return authList;
}
private todoapp.models.User getUserDetail(String username){
todoapp.models.User user = users.findByUsername(username);
return user;
}
}
TodoController
#RestController
#RequestMapping("/api/todos")
public class TodoController {
#Autowired
TodoRepository todoRepository;
#RequestMapping(method=RequestMethod.GET)
public List<Todo> getAllTodos() {
return todoRepository.findAll();
}
#RequestMapping(method=RequestMethod.POST)
public Todo createTodo(#Valid #RequestBody Todo todo) {
return todoRepository.save(todo);
}
#RequestMapping(value="{id}", method=RequestMethod.GET)
public ResponseEntity<Todo> getTodoById(#PathVariable("id") String id) {
Todo todo = todoRepository.findOne(id);
if(todo == null) {
return new ResponseEntity<Todo>(HttpStatus.NOT_FOUND);
} else {
return new ResponseEntity<Todo>(todo, HttpStatus.OK);
}
}
#RequestMapping(value="{id}", method=RequestMethod.PUT)
public ResponseEntity<Todo> updateTodo(#Valid #RequestBody Todo todo, #PathVariable("id") String id) {
Todo todoData = todoRepository.findOne(id);
if(todoData == null) {
return new ResponseEntity<Todo>(HttpStatus.NOT_FOUND);
}
todoData.setTitle(todo.getTitle());
todoData.setCompleted(todo.getCompleted());
Todo updatedTodo = todoRepository.save(todoData);
return new ResponseEntity<Todo>(updatedTodo, HttpStatus.OK);
}
#RequestMapping(value="{id}", method=RequestMethod.DELETE)
public void deleteTodo(#PathVariable("id") String id) {
todoRepository.delete(id);
}
}
RecourceController
#Configuration
public class ResourceController extends WebMvcConfigurerAdapter{
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/api/todos").setViewName("home");
registry.addViewController("/register").setViewName("register");
registry.addViewController("/login").setViewName("login");
}
}
Any help will be greatly appreciated.
This is the Project Layout.
You forgot to add .html to your view names:
registry.addViewController("/").setViewName("app/views/index.html");
registry.addViewController("/api/todos").setViewName("app/views/home.html");
registry.addViewController("/register").setViewName("app/views/register.html");
registry.addViewController("/login").setViewName("app/views/login.html");
Spring Boot registers a ResourceHttpRequestHandler which is capable of resolving static resources under static folder.
Because you set login as view name ResourceHttpRequestHandler tries to load static/login which apparently does not exist.
Change it to app/views/login.html so that static/login becomes static/app/views/login.html.
I made a windows service using C# as follow
public partial class Housekeeping : ServiceBase
{
#region Fields
private ManualResetEvent _ResetEvent = new ManualResetEvent(false);
private RegisteredWaitHandle _RegisteredWaitHandle;
private long _Interval = 60000;
private Logger _Logger;
#endregion
#region Constructors
public Housekeeping()
{
InitializeComponent();
_Interval = _Interval * Convert.ToInt32(ConfigurationManager.AppSettings["RunningInterval"]);
_Logger = new Logger();
}
#endregion
#region Properties
#endregion
#region Behaviors
public void Housekeep(object state, bool timeout)
{
try
{
// my code
}
catch (Exception ex)
{
// my code
}
}
protected override void OnStart(string[] args)
{
_RegisteredWaitHandle = ThreadPool.RegisterWaitForSingleObject(_ResetEvent, new WaitOrTimerCallback(Housekeep), null, _Interval, false);
}
protected override void OnStop()
{
}
protected override void OnContinue()
{
base.OnContinue();
}
protected override void OnPause()
{
base.OnPause();;
}
}
and on the main
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Housekeeping()
};
ServiceBase.Run(ServicesToRun);
}
}
I Installed the WS using InstallUtil.exe, but when I tried to start the WS I got this error "error 1053: the service did not respond to the start or control request in a timely fashion". I surfed around but all the solution are for a windows server 2003 issue and I'm running Windows 10.
How can I solve this issue?
Last time I have seen this issue, it got resolved by changing the compiling option from 'Debug' to 'Release'.
I have a Service.class ValueProxy in a service oriented architecture (i have a server method like "storeService(service)".
I would use an Editor with RequestFactoryEditorDriver.
I expect all work, but when i call driver.edit(service) i get a null delegate exception.
Why? It's a bug?
At http://crazygui.wordpress.com/tag/editor/ i find a sample of implementation...only differece with mine is SimpleBeanRequestEditorDriver.class (i have RequestFactoryEditorDriver.class)
ServiceEditor.class
public class ServiceEditor extends Composite implements Editor<ServiceProxy>{
private static final Logger logger = Logger.getLogger(ServiceEditor.class.getName());
private static ServiceEditorUiBinder uiBinder = GWT
.create(ServiceEditorUiBinder.class);
interface ServiceEditorUiBinder extends
UiBinder<Widget, ServiceEditor> {
}
//~Driver ==========================================================================================================================
interface Driver extends RequestFactoryEditorDriver<ServiceProxy, ServiceEditor> {
}
Driver driver;
//====================================================================================================================================
#UiField
Decorator<String> name;
#UiField
Decorator<String> description;
#UiField
Decorator<String> notes;
#UiField
Decorator<String> citiesString;
// #UiField(provided=true)
// Decorator<String> category;
// MultiWordSuggestOracle oracle = new MultiWordSuggestOracle();
// #UiField(provided=true)
// #Ignore
// SuggestBox suggestBox = new SuggestBox(oracle);
private BigInteger organizationId;
private EditorDelegate<ServiceProxy> delegate;
public ServiceEditor() {
initWidget(uiBinder.createAndBindUi(this));
driver = GWT.create(Driver.class);
}
#Override
protected void onLoad() {
driver.initialize(ClientFactory.AppInjector.getRequestFactory(),this);
}
public void edit() {
ServiceRequestContext requestContext = ClientFactory.AppInjector.getRequestFactory().getNewServiceContext();
edit(requestContext.create(ServiceProxy.class),requestContext);
}
public void display(ServiceProxy p){
driver.display(p);
}
public void edit(ServiceProxy p) {
ServiceRequestContext requestContext = ClientFactory.AppInjector.getRequestFactory().getNewServiceContext();
edit(p,requestContext);
}
public void edit(ServiceProxy service,ServiceRequestContext requestContext) {
if(service.getToken()==null) {
requestContext.addServiceToOrganization(organizationId, service);
//TODO: attenzione a tempistiche chiamate;
SessionRPC.Util.getInstance().getOrganizationId(new AsyncCallback<BigInteger>() {
#Override
public void onSuccess(BigInteger result) {
organizationId = result;
}
#Override
public void onFailure(Throwable caught) {
}
});
}
else
requestContext.updateService(service);
driver.edit(service,requestContext);
}
public RequestContext flush2(){
return driver.flush();
}
public void submit(Receiver<Void> receiver){
RequestContext context = driver.flush();
if (driver.hasErrors()) {
Window.alert("Driver errors!");
return;
}
context.fire(receiver);
}
public void notifyErrors(Set<ConstraintViolation<?>> violations) {
driver.setConstraintViolations(violations);
//driver.getErrors().get(0).
logger.info("Validation Errors: /n "+driver.getErrors().toString());
}
// #Override
// public void setDelegate(EditorDelegate<ServiceProxy> delegate) {
// this.delegate = delegate;
// }
}
ActivitySnippet...
ServiceEditor serviceEditor = GWT.create(ServiceEditor.class);
serviceEditor.display(response);
Stack trace...
Caused by: com.google.gwt.core.client.JavaScriptException: (TypeError) : Cannot set property 'request' of undefined
at Unknown.$collect(JsArrayString.java:42)
at Unknown.fillInStackTrace_2(StackTraceCreator.java:180)
at Unknown.fillInStackTrace_0(StackTraceCreator.java:518)
at Unknown.fillInStackTrace(Throwable.java:115)
at Unknown.Throwable_0(Throwable.java:51)
at Unknown.Exception_0(Exception.java:25)
at Unknown.RuntimeException_0(RuntimeException.java:25)
at Unknown.JavaScriptException_1(JavaScriptException.java:117)
at Unknown.JavaScriptException_0(JavaScriptException.java:109)
at Unknown.getCachableJavaScriptException(Exceptions.java:45)
at Unknown.wrap(Exceptions.java:29)
at Unknown.$setRequestContext(RequestFactoryEditorDelegate.java:80)
at Unknown.$edit(AbstractRequestFactoryEditorDriver.java:168)
at Unknown.display_0(AbstractRequestFactoryEditorDriver.java:159)
at Unknown.$show_2(ServiceEditor.java:91)
This means that getDelegate() method (line 168 of AbstractRequestFactoryEditorDriver.class) return null.
If you call RequestFactoryEditorDriver.show, it essentially just calls RequestFactoryEditorDriver.edit, but without a requestcontext. This otherwise should follow the same basic path in terms of how the driver needs to be wired up.
In this case, if the delegate is null, then the driver hasn't been initialized. From your code:
public ServiceEditor() {
initWidget(uiBinder.createAndBindUi(this));
driver = GWT.create(Driver.class);
}
#Override
protected void onLoad() {
driver.initialize(ClientFactory.AppInjector.getRequestFactory(),this);
}
public void edit() {
ServiceRequestContext requestContext = ClientFactory.AppInjector.getRequestFactory().getNewServiceContext();
edit(requestContext.create(ServiceProxy.class),requestContext);
}
public void display(ServiceProxy p){
driver.display(p);
}
You never listed the code that shows when edit or display are being called, so I'm mostly guessing here, but it looks like your other code looks roughly like this:
ServiceEditor editor = new ServiceEditor();//create ui, create driver.
editor.display(data);//driver.display, which calls driver.edit
parentWidget.add(editor);// causes onLoad to be called if actually
//attached to the dom, which causes driver.initialize
This is wrong. The driver must be initialized before you attempt to edit or display, since otherwise it doesn't know which editor objects it should be working with.
Instead, move driver.initialize to earlier than onLoad, like in the ServiceEditor constructor itself, or in some init method which allows you to call it earlier deliberately. Another option is to just call parent.add(editor) before editor.display(), though this may not work - make sure you understand what causes onLoad to be called.
(Please note that ServiceEditor.show is in your stack trace but not in your code listing, so I can't tell if the chance would be more obvious in seeing this.)
I am having an issue getting an initial RPC call to load data when the module is loaded.
I am adapting code from here and here.
The error that if fails on is a null pointer, and it behaves as if it is not even making the RPC call at all, since neither debug messages inside of the RPC appear in the test console in Eclipse.
The MenuItems object is an ArrayList < ArrayList < String > > object that implements IsSerializable and has a SerializableWhiteList entry as per this SO answer. This object is generated in an RPC RemoteServiceServlet.
The console also references the line
History.fireCurrentHistoryState();
in AppController.java (almost identical to the GWT Contacts example)
Ideas on why/where/how this is going astray? Any other implementation examples of initial RPC calls would be great also.
public class MVPtest implements EntryPoint {
MenuItems mItems;
public void onModuleLoad() {
MainServiceAsync rpcService = GWT.create(MainService.class);
System.out.println("Inside of mod load. rpcService = " + rpcService.toString());
rpcService.getMenuItems(new AsyncCallback<MenuItems>() {
public void onFailure(Throwable caught) {
System.out.println("I failed...");
caught.printStackTrace();
}
public void onSuccess(MenuItems result) {
System.out.println("I got the menuitems.");
mItems = result;
}
});
HandlerManager eventBus = new HandlerManager(null);
AppController appViewer = new AppController(rpcService, eventBus, mItems);
appViewer.go(RootLayoutPanel.get());
}
}
The rpcService debug message yields a non-null:
Inside of mod load. rpcService = com.******.******.test.client.MainService_Proxy#4f07f3b5
This statement is dangerous:
AppController appViewer = new AppController(rpcService, eventBus, mItems);
because your code on the client side will be executed without witing for the response of your call.
Something like this should work:
public class MVPtest implements EntryPoint {
MenuItems mItems;
public void onModuleLoad() {
MainServiceAsync rpcService = GWT.create(MainService.class);
System.out.println("Inside of mod load. rpcService = " + rpcService.toString());
rpcService.getMenuItems(new AsyncCallback<MenuItems>() {
public void onFailure(Throwable caught) {
System.out.println("I failed...");
caught.printStackTrace();
}
public void onSuccess(MenuItems result) {
System.out.println("I got the menuitems.");
mItems = result;
HandlerManager eventBus = new HandlerManager(null);
AppController appViewer = new AppController(rpcService, eventBus, mItems);
appViewer.go(RootLayoutPanel.get());
}
});
}
}