I have a class which is used to generate endpoints to the save in Google Cloud Datastore. I populate objects of this class on the application side and then call the generated API to store them (I'm using Objectify)
I've recently added a new field of type List<String> including a method to add strings to the list. However on the application said I can only see the old version of the class (which is imported from backend.MyApi.model.MyClass)
The culprit according to Android Studio is in backend/build/libs/backend-android-endpoints.jar which has a MyClass.class object
I've tried deleting the build files in the backend module, cleaning and rebuilding but it still uses the old version
How do I force the class to be rebuilt using the new source to include the new fields/methods?
So I think I've found the solution.
Any class defined as an entity by Objectify shows up in API.model but only with getters and setters for its defined fields. Therefore my add method isn't part of it
Therefore to include the functionality of add() instead on the application side I write
List<String> classList = classInstance.getClassList();
String stringToAdd = "Blah";
if (!classList.contains(stringToAdd))
{
classList.add(stringToAdd);
classInstance.setClassList(classList)
}
Related
I am currently facing problems integrating the existing Piketec TPT Java API (http://javadoc.jenkins.io/plugin/piketec-tpt/com/piketec/tpt/api/package-summary.html) in a Java project by using Reflection.
The TPT Api provides an interface called "TptApi", which contains several abstract methods, that are used to access TPT projects.
I have already integrated other APIs such as the Dox4j-API, where a class instance was used as invokation target. Obvisouly, this is not the correct way for accessing method from an interface.
My goal is to access the method "OpenResult openProject(File f)" from the TptApi interface (http://javadoc.jenkins.io/plugin/piketec-tpt/com/piketec/tpt/api/TptApi.html#openProject-java.io.File-).
My code:
ClassLoader cl = new URLClassLoader(...);
Map c = new HashMap();
File file = new File("test.prj");
c.put("TptApi", cl.loadClass("com.piketec.tpt.api.TptApi"));
c.put("OpenResult", cl.loadClass("com.piketec.tpt.api.OpenResult"));
//The way I did it with 'normal' classes, not applicable with the interface:
//Object target = ((Class) c.get("TptApi")).newInstance();
OpenResult or = (OpenResult)((Class) c.get("TptApi")).getMethod("openProject", new Class[]{File.class}).invoke(target, new Object[]{_file});
So how do I access abstract interface methods by Reflection?
I just stumbled over this Question so let me answer it even if it is a bit outdated. I read in your comments that you assume you do not need the TPT tool itselfe to use the API. That is simply wrong. The API is just a way to communicate via RMI with an open TPT instance. To connect to TPT the TPT instance must have enabled RMI and you have to know the configurable port and binding name. You can do that in the Preferences under "TPT API" or by starting TPT with command line arguments "--apiPort " and "--apiBindingName ". Now you can obtain the TptApi instance using these two lines of code:
Registry registry = LocateRegistry.getRegistry(HOST, PORT); // get Server/RMI-Registry
TptApi remoteApi = (TptApi)registry.lookup(BINDING_NAME); // get TPT-API
My initial post did not assume that TPT is not necessary for the usage of the API. It indeed is. The way how to enable the API in TPT is well-documented, the two lines of code you posted are also ok. The problem I described is to access the API by using Java reflection. For other APIs I could do this by using "newInstance" to get access to the tool. With TPT, the corresponding API object is an interface instead of a class, so there is no way to instantiate it. Therefore I wanted to know how this specific API can be accessed via reflection.
I'm attempting to compile a Google Cloud Endpoints project in Java, but I'm getting the following error:
There was an error running endpoints command get-client-lib: Object type K not supported.
I don't have any public methods in any of my API classes that take in or return a generic type (K or otherwise), nor any class specifically named K. My body types should all be entity types by the documentation's definitions.
The biggest change I've made recently is that I moved my model (which defines the entity types) to a separate project and I'm including those classes as a JAR dependency.
I'm on the App Engine SDK version 1.9.51 (recently upgraded to this), though using previous versions doesn't seem to change anything. I'm using Gradle with the gradle-appengine-plugin (eventually planning to migrate to the newer app-gradle-plugin).
Any thoughts on why this is happening, and what steps I might take to resolve?
EDIT:
I seem to have isolated the problem, but it hasn't resolved the issue.
I have a list method in my API that returns an object containing a list of other objects. Something like:
public class ListWrapper() implements Serializable {
private List<Object> list;
public List<Object> getList() { return list; }
public void setList(List<Object> list) { this.list = list; }
}
It seems to be this List type which is suddenly the problem. If I remove it from the class, it works fine. If I edit the method to return something else, it works fine. But, in a previous version of the code, this LsitWrapper object existed and was returned exactly as it is and worked fine. What has changed? (Reverting back to earlier versions of the App Engine SDK doesn't seem to help.)
So basically I'm trying to create a settings manager for users. Once I save the class in MongoDB and then redirect to another sector it throws an error similar to this - http://hastebin.com/isenakibaj.java (Error). I'm using the class loader from the Plugin class. This works fine on the server with the class 'HubSettings', that extends 'SettingsEntry', but when I change server to one without the HubSettings class as it has no intention to use it (different build) it doesn't like it.
Morphia stores the class type as part of the document. When you try to load that document, morphia tries to load that class when loading documents from the database. you'll either need to tweak the data in your database or make that class avaiable at runtime.
I try to create a template object of task using existing task object. When i use a special constructor I get the error:
incompatible types: Task cannot be converted to TaskTemplate
Here is the code I'm using the create the TaskTemplate:
TaskTemplate bean = new TaskTemplate(newTask);
Here is the constructor I'm calling:
public TaskTemplate(Task task) {
this.setTitle(task.getTitle());
this.setDate(task.getDate());
}
But when I set all properties in the place where object is created everything is ok.
TaskTemplate bean = new TaskTemplate();
bean.setTitle(newTask.getTitle());
bean.setDate(newTask.getDate());
Why does it happen?
How can I create a constructor which will get a task and create a template?
It is highly likely that you need to rebuild your project.
This kind of problem can happen when the compiled class the calling code is using is out of date with the source code you are viewing, causing great consternation when recent changes (such as creating a new constructor) do not seem to exist from the perspective of the calling code.
Most IDEs automatically rebuild as you code: Check that your IDE is configured to build automatically. If you aren't using an IDE, consider using one.
I seem to be having an issue with Java and NetBeans when it comes to writing web services.
I have searched for a couple of days with no luck, finding people with the same issue as me with zero replies.
I have created a web service which returns a complex type (LoginReply), and that complex type contains an array of another complex type (AppInfo)
However when I generate the WSDL from this, the complex type definition in the XSD is blank, and manually adding the information still makes the web service return null even when data is successfully passed to the web service.
<xs:complexType name="appInfo">
<xs:sequence/>
</xs:complexType>
LoginReply: http://pastebin.com/Umx6ayvi
AppInfo: http://pastebin.com/566WnZ4H
If anyone could point out what I'm doing wrong, or if this is a bug with NetBeans, I'm new to Java so I can't rule out that I'm simply not understanding something, but I'm close to pulling my hair out here.
EDIT:
Just noticed when i deploy to tomcat via NetBeans I get the following error:
WARNING: duplicate class definition bug occured? Please report this : uk/co/example/ComplexTypes/LoginReply$JaxbAccessorM_getApplications_setApplications_[Luk_co_example_ComplexTypes_AppInfo;
java.lang.ClassFormatError: Illegal class name "uk/co/example/ComplexTypes/LoginReply$JaxbAccessorM_getApplications_setApplications_[Luk_co_example_ComplexTypes_AppInfo;" in class file uk/co/example/ComplexTypes/LoginReply$JaxbAccessorM_getApplications_setApplications_[Luk_co_example_ComplexTypes_AppInfo;
Notice the random L before co_uk_example. My research suggests this is an old bug that should be fixed, and that no one else has reported this issue in over a year, no sure where to go from here.
Another edit:
Just added a new web method on the service that simply gets a list of appInfo and returns it to the client. This still fails the same way with NetBeans refusing to generate a sequence inside AppInfo.
I'm sure I'm missing something to declare the class, but I have checked it countless times to ensure I'm not missing anything.
warning gives you good hint: "WARNING: duplicate class definition bug occured"
your ws implementation class directly uses LoginReply class which directly uses AppInfo (+you are maybe also directly using this class in your ws implementation) => jaxb finds it
#XMLSeeAlso(...) tells jaxb to "link" referenced class
=> two definitions of the same class (not sure if it is by design or a bug that jaxb is not able to handle this case more gracefully)
to fix this just remove #XmlSeeAlso from your LoginReply class and you should be fine
This Issue came down to a very simple mistake. The AppInfo class was using non-standard getters and setters.
public void SetAppID(int AppID)
{
this.AppID = AppID;
}
This is INCORRECT (notice the capital on the Set), it should be:
public void setAppID(int AppID)
{
this.AppID = AppID;
}
Using a capital is not standard for JavaBeans and as such JAX-WS didn't know how to generate WSDL for this class. Thanks too shyam from the following link for answering the question
How to return a custom complex type in JAX-WS web services?
I don't think you can send "complex types" over the net (programmed port types) in http protocol, however an array may be implicitly converted to a delimited string set , check the docs for data transfer.