Disclaimer: I'm new to GWT/PlayN, so this might be an obvious mistake that I'm making.
When I have a basic (starter) PlayN project, my BlahGame class method implements the Game interface, which requires three methods: init, paint, and update. The starter class looks something like:
public class BlahGame implements Game {
public void init() { ... }
public void paint(float alpha) { ... }
public void update(float alpha) { ... }
}
I created a BaseGame class to implement game, like so:
public class BaseGame implements Game {
public void init() { ... }
public void paint(float alpha) { ... }
public void update(float alpha) { ... }
}
My main game class then became a sublass of BaseGame like so:
public class BlahGame extends BaseGame {
public void init() { ... base.init(); ... }
}
Everything compiles and works from Java. But when I try to GWT-compile the HTML version of my game, I get this error:
com.google.gwt.dev.jjs.InternalCompilerException: Failed to get JNode
at com.google.gwt.dev.jjs.impl.TypeMap.get(TypeMap.java:140)
at com.google.gwt.dev.jjs.impl.TypeMap.get(TypeMap.java:71)
at com.google.gwt.dev.jjs.impl.BuildTypeMap.getType(BuildTypeMap.java:730)
...
[ERROR] <no source info>: public class com.deengames.BaseGame
extends java.lang.Object
implements : playn.core.Game
/* methods */
public void <init>()
public void init()
[unresolved] public void paint(float)
[unresolved] public void update(float)
[unresolved] public int updateRate()
I'm not sure what I'm missing here. Is it that some GWT classes need to be updated? Or is it something else? I had expected the HTML vesrion to compile since the Java version compiles; the signatures of the classes shouldn't change from subclassing.
Edit: I'm using a brand new, boilerplate PlayN project. In the class, if I extend the base class AND implement the interface, it still doesn't compile; only removing the base class extension works.
This is your problem right here:
[ERROR] <no source info>: public class com.deengames.BaseGame
You have put code in the top-level package com.deengames. I bet that your GWT module file is also in that same package directory, probably something like com/deengames/MyGame.gwt.xml. The GWT module file has to specify sub-package directories for all code that GWT will see.
When you generate a project using the PlayN Maven archetype, it has this structure:
core/src/main/java/com/foozle/core/Barzle.java
core/src/main/java/com/foozle/resources/images/bg.png
html/src/main/java/com/foozle/Barzle.gwt.xml
html/src/main/java/com/foozle/html/BarzleHtml.java
All of the game code is in the com.foozle.core package and the resources are in the com.foozle.resources package. If you look at the generated Barzle.gwt.xml file you will see:
<module rename-to='barzle'>
<inherits name='playn.PlayN'/>
<source path='core'/>
<source path='html'/>
<public path="resources" />
<entry-point class='com.foozle.html.BarzleHtml'/>
</module>
The two <source> lines explicitly add the com.foozle.core and com.foozle.html sub-packages to the GWT project. Anything that is not explicitly listed in this GWT module file will be ignored by GWT. Due to the way GWT specifies these packages, it is not possible to add the top-level package to your GWT project. You cannot use:
<source path=""/>
or:
<source path="."/>
You have to put all of your code in sub-packages that are explicitly enumerated in your GWT module file.
I presume there is an issue with the BlahGame.gwt.xml file inclusions. Make sure all the directories are included in that file, as sources. The structure should be similar to:
<module rename-to='blah'>
<inherits name='playn.PlayN' />
<source path='core'/>
<source path='common'/>
... etc ...
<source path='html'/>
<public path="resources" />
<entry-point class='full.namespace.BlahGameHtml' />
</module>
Additionally, your BlahGameHtml.java class should look something like:
public class BlahGameHtml extends HtmlGame
{
#Override
public void start()
{
HtmlAssetManager assets = HtmlPlatform.register().assetManager();
assets.setPathPrefix("blah/");
PlayN.run(new BlahGame());
}
}
Related
I am using AJDT 2.2.4 which is build on AspectJ 1.81.
Consider this simple aspect:
#Aspect
public class SampleAspect {
#Before("#annotation(logMe)")
public void beforeAdvice(JoinPoint joinPoint, LogMe logMe) {
System.out.println("Before the method");
}
}
It print some text before LogMe annotation which is :
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface LogMe {}
Now, I apply this annotation to some method as:
public class DummyClass {
#LogMe
public void doSomething() {
SampleUtil sampleUtil = new SampleUtil();
//pass null for simplicity !
sampleUtil.sampleMethod(null);
System.out.println("Do Something");
}
}
The SampleUtil is
public class SampleUtil {
public void sampleMethod(
Map<String, Object>[] mapArray){
}
}
I get this warning:
can not resolve this member:
void foo.SampleUtil.sampleMethod(java.util.Map[]) [Xlint:unresolvableMember]
If I change the sampleMethod parameter to something else like Map<String, Object> aMap the error will go.
Why do I get this warning ?!
That warning means that it can't find foo.SampleUtil on the inpath. The inpath is similar to the classpath, and is used to determine what the aspects weave against.
I am guessing that foo.SampleUtil is in another project and this means that you need to explicitly add the project to your inpath.
Since you are using AJDT inside of Eclipse, you can go to the aspect project's properties page and select the AspectJ build path tab. Choose Inpath and add the other project.
i am in this situation:
#RemoteServiceRelativePath("create_event")
public interface CreateEventService extends RemoteService {
String[] createeventServer(LinkedList<LinkedList<String>> input) throws IllegalArgumentException;
}
public interface CreateEventServiceAsync {
void createeventServer(LinkedList<LinkedList<String>> input, AsyncCallback<String[]> callback)
throws IllegalArgumentException;
}
public class CreateEventServiceImpl extends RemoteServiceServlet implements CreateEventService {
public String[] createeventServer(LinkedList<LinkedList<String>> input) throws IllegalArgumentException {
String[] arr = new String[2];
...
return arr;
}
Why does this cause error "The response could not be deserialized"?
p.s. I have tried to execute the project with app engine and without it, but the problem is the same.
To problems with serializable objects, you can try this check list:
Verify that the class has a default constructor (without arguments)
Verify that the class implements Serializable or IsSerializable or
implements an Interface that extends Serializable or extends a class
that implement Serializable
Verify that the class is in a client.* package or …
Verify, if the class is not in client.* package, that is compiled in
your GWT xml module definition. By default is present. If your class
is in another package you have to add it to source. For example if
your class is under domain.* you should add it to xml as . Be aware
that the class cannot belong to server package! More details on GWT
page:
http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideModuleXml
If you are including the class from another GWT project you have to
add the inherits to your xml module definition. For example if your
class Foo is in the package com.dummy.domain you have to add to the
module definition. More details here:
http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideInheritingModules
If you are including the class from another GWT project released as
a jar verify that the jar contains also the source code because GWT
recompile also the Java source for the classes passed to the Client.
Font: http://isolasoftware.it/2011/03/22/gwt-serialization-policy-error/
I have a factory class which imports a list of IOperation types. I get the following error when I try and resolve the factory class:
Resulting in:
Cannot activate part
'Message36Operation'. Element:
Message36Operation -->
Message36Operation --> DirectoryCatalog
(Path=".\")
Resulting in:
Cannot get export 'Message36Operation
(ContractName="IOperation")' from part
'Message36Operation'. Element:
Message36Operation
(ContractName="IOperation") -->
Message36Operation --> DirectoryCatalog
(Path=".\")
Resulting in:
Cannot set import
'OperationsFactory.Operations
(ContractName="IOperation")' on part
'OperationsFactory'. Element:
OperationsFactory.Operations
(ContractName="IOperation") -->
OperationsFactory --> AssemblyCatalog
(Assembly="RmiToODKMessanger, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null")
Here's what I have:
[Export(typeof(OperationsFactory))]
public class OperationsFactory
{
[ImportMany(typeof(IOperation))]
private IEnumerable<IOperation> Operations { get; set; }
}
public interface IOperation
{
}
public abstract class BaseRmiOperation : IOperation
{
}
[Export(typeof(IOperation))]
public class Message36Operation : BaseRmiOperation, IOperation
{
}
The exception is thrown will I try and resolve an instance of the factory.
I can get this to work if I remove the abstract class.
Any ideas,
Thanks,
Ken
** Update:
Below is the BaseRmiOperation class. I'm instantiating a few classes in the cstor and that's it.
I forgot to mention the structure of the app previously.
CG.App: contains OperationsFactory and bootstrapper class for MEF.
CG.Plugins : Contains various IOperation implementations such as Message36Operation and the BaseRmiOperation abstract class
CG.Common : Contains IOperation interface. This assembly is referenced by both CG.App and CG.Plugins
The CG.App.Bootstrapper class loads the plugins from bin/plugins.
public abstract class BaseRmiOperation : IOperation
{
protected SettingsManager _settingsManager;
protected RmiMessenger _messenager;
protected ILogger _logger;
protected TagManager _tagManager;
protected Environments _rmiEnvironment;
protected string _msgSource;
protected string _emp_id;
public BaseRmiOperation()
{
this._settingsManager = new SettingsManager();
this._messenager = new RmiMessenger(null, null);
this._tagManager = new TagManager(); // pass ILogger
//this._logger = logger;
// pulls the rmi_env and a few other settings from
// winCC.
PopulateRmiSettings();
}
public abstract ExitCodes Execute(object[] data);
public abstract string Description { get; }
public abstract string Alias { get; }
Sorted the problem. Silly mistake. The TagManager assembly was not present in the /bin folder and was causing the BaseRmiOperation cstor to crash. A breakpoint at the start of the cstor was never being called, it always crashed on the line to resolve the OperationFactory. Figured it out by going back to basics and adding functionality one line at a time. Thanks.
I have a problem using Gin. Here is a simple example.
#GinModules(AppModule.class)
public interface AppInjector extends Ginjector
{
MainForm getMainPanel();
TemplateForm getHeaderForm();
}
then here is Module
import com.google.inject.Singleton;
public class AppModule extends AbstractGinModule
{
#Override
protected void configure()
{
bind(MainForm.class).in(Singleton.class);
}
}
and the Entry point
public class MySampleApplication implements EntryPoint
private final AppInjector injector = GWT.create(AppInjector.class);
public void onModuleLoad()
{
MainForm mf = injector.getMainPanel();
RootPanel.get().add(mf);
}
}
And the module xml file
<module rename-to="MySampleApplication">
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User'/>
<!-- Specify the app entry point class. -->
<entry-point class='com.mySampleApplication.client.MySampleApplication'/>
<inherits name="com.google.gwt.inject.Inject"/>
<!-- Specify the app servlets. -->
<servlet path='/MySampleApplicationService' class='com.mySampleApplication.server.MySampleApplicationServiceImpl'/>
</module>
After i run this code i got an exception :
ERROR: Failed to create an instance of 'com.mySampleApplication.client.MySampleApplication' via deferred binding . java.lang.RuntimeException: Deferred binding failed for 'com.mySampleApplication.client.gin.AppInjector' (did you forget to inherit a required module?).
I tried with gin 1.0 and guice 2.0.
Please, advice.
Thanks.
#GinModules(AppClientModule.class)
should probably be
#GinModules(AppModule.class)
Update:
The error is in line declaring AppInjector. It should be:
interface AppInjector extends Ginjector {
I have some questions regarding gwt-dispatch and guice. I'm using Guice 2.0, gwt-dispatch 1.1.0 snapshot, mvp4g 1.1.0 and GIN 1.0
First of all, I have defined simple action, result and handler:
ListContactsAction.java
public class ListContactsAction implements Action<ListContactsResult>{
public ListContactsAction() {
}
}
ListContactsResult.java
public class ListContactsResult implements Result {
private List<Contact> contactList;
public ListContactsResult() {
}
public ListContactsResult(List<Contact> contactList) {
this.contactList = contactList;
}
public List<Contact> getContactList() {
return contactList;
}
}
ListContactsHandler.java
public class ListContactsHandler implements ActionHandler<ListContactsAction, ListContactsResult>{
#Inject
private SqlSessionFactory factory;
public Class<ListContactsAction> getActionType() {
return ListContactsAction.class;
}
public ListContactsResult execute(ListContactsAction a, ExecutionContext ec) throws DispatchException {
// some code using SqlSessionFactory and returning ListContactResult
// with list of contacts
}
public void rollback(ListContactsAction a, ListContactsResult r, ExecutionContext ec) throws DispatchException {
/* get action - no rollback needed */
}
}
In previous version of my app, which was using rpc service instead of command pattern, I had a method which was providing SqlSessionFactory for injections, something like this:
#Provides
public SqlSessionFactory getSqlSessionFactory(){
// some code here
}
I read on gwt-dispatch getting started that I have to provide binding between my action and it's handler, which should look something like that:
public class ContactModule extends ActionHandlerModule{
#Override
protected void configureHandlers() {
bindHandler(ListContactsAction.class, ListContactsHandler.class);
}
}
But I have problem wiring it all with Guice, because this example from gwt-dispatch site:
public class DispatchServletModule extends ServletModule {
#Override
public void configureServlets() {
serve( "/path/to/dispatch" ).with( DispatchServiceServlet.class );
}
}
doesn't work, since there is no DispatchServiceServlet in the package.
My questions are:
How should I write DispatchServletModule and how to make it going (with what I should serve path)
what should I put in the web.xml file of my app to be able to correctly execute actions from my presenter, which has GIN injected DispatcherAsync implementation
Where should I put my SqlSessionFactory providing method (in which module) to be able to inject SqlSessionFactory where I need it
How I instantiate the injector so then I can use it in other action handlers properly
I think that is all and I made myself clear. If something isn't clear enough, I'll try to be more specific.
Have you created a GuiceServletConfig class? This is where you setup your Dispatch servlet module as well as your action handler module with Guice.
plubic class GuiceServletConfig extends GuiceServletContextListener {
#Override
protected Injector getInjector() {
return Guice.createInjector(new HandlerModule(), new DispatchServletModule());
}
}
The HandlerModule is your ActionHandler module class, so from your code you would put your ContactModule class.
For your SqlSessionFactory, you could setup the binding for it in your ContactModule, with my code I only have a single ServerModule that sets up all my service and action handler bindings. This is mainly for the sake of simplicity.
GWT-Platform framework uses a gwt-dispatch fork to handle rpc requests. There's a lot of code, which you probably had to wtite yourself, if you think of seriously using dispatcher and Guice. I highly recommend it.
Firstly, I sympathise. Putting this all together isn't documented in any one spot. I'll answer each of your questions in turn. Add comments to my answer if any of it is unclear.
QU: How should I write DispatchServletModule and how to make it going (with what I should serve path)?
There's a GuiceStandardDispatchServlet class in the net.customware.gwt.dispatch.server.guice package; use that. I'm not 100 percent sure why, but the path I use includes the name of my GWT module, followed by '/dispatch'. You might have to experiment with that.
public class MyServletModule extends ServletModule {
#Override protected void configureServlets() {
serve("/com.my.module.name/dispatch")
.with(GuiceStandardDispatchServlet.class);
}
}
QU: what should I put in the web.xml file of my app to be able to correctly execute actions from my presenter, which has GIN injected DispatcherAsync implementation?
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>com.myapp.whatever.MyContextListener</listener-class>
</listener>
...
</web-app>
... and then you'll need a custom context listener that creates a Guice injector as follows. Notice that I've included your ContactModule, which binds action handlers.
public class MyContextListener extends GuiceServletContextListener {
#Override protected Injector getInjector() {
return Guice.createInjector(new MyServletModule(),
new ContactModule(), new SQLStuffModule());
}
}
QU: Where should I put my SqlSessionFactory providing method (in which module) to be able to inject SqlSessionFactory where I need it?
Notice that I included a new SQLStuffModule in the previous code snippet; that would be a good place to put your SqlSessionFactory binding. There's no harm having multiple modules, and I find that it keeps the various concerns nicely separated.
QU: How I instantiate the injector so then I can use it in other action handlers properly?
For the server-side, see the MyContextListener code snippet above.
On the client side, you'll need a custom injector interface something like this:
#GinModules(StandardDispatchModule.class, MyClientModule.class)
public interface MyGinjector extends Ginjector {
MyWidgetMainPanel getMainPanel();
}
...and you can bind your MVP stuff in a custom Gin module as follows. I'm sorry that I'm not familiar with mvp4g, but I assume that you'll need to wire the views and presenters together in the module class.
public class MyClientModule extends AbstractGinModule {
#Override protected void configure() {
bind(...).to(...);
...
}
}