What I was using before:
- Eclipse
- Tomcat
- Maven multi module projects
- Netbeans
- Any JavaEE container, including Glassfish
- Maven simple module project
However in order to get going "keeping it simple", I had to go through some setup stuff - and as per usual I had to dig all over the net to put a complete picture together. So I'm just going to create this article and document it all in one place once and for all. In this document I am going to detail:
- How to configure an alien datasource in Glassfish; and by alien I mean HSQL, a JDBC driver that the server doesn't even know. Just to stress it out.
- Setting up a simple Maven JavaEE application in Netbeans 8.x, lightweight the Adam Bien way
- Setting up a startup EJB to create fixture data to test with
- Creating a RESTFul webservice resource to spew out said fixture data
Target audience
I'm sure everyone can find something of use in this article whether you're completely new to JavaEE development or a veteran who like me was ready to shoot Eclipse into orbit around the moon, but keep in mind that this article is not here to teach you the many depths of JavaEE development and focuses only on the setup requirements to get going with Netbeans and how to do it the easy and lightweight way.This article uses Glassfish V4.1 as the application server. Why? Because that is what comes with Netbeans, so why not? Glassfish works just as well as a WildFly or a TomEE, but if you'd want to use any other container you'd have to install it and manually set it up. That's wasted time.
Speaking of which, why Netbeans and not say IntelliJ which has really skyrocketed in popularity lately? I am a big fan of IntelliJ and it works exceptionally well for any kind of development, but it isn't free software - at least the version which supports JavaEE development isn't. So I settle for the other-best-thing, which really is Netbeans. But let it be known that even though I write this article, I do not recommend Netbeans over IntelliJ, nor do I recommend IntelliJ over Netbeans. You should do a trial and see which one fits you like a glove.
There is also the matter of operating system; I use Windows, that is just what I grew up with and thus what I'm comfortable with even though I recognize the benefits of a Linux shell environment for developers. As such screenshots and path recommendations will be Windows-based. I make the assumption that when you use Linux or Mac for programming, you know how your OS works and can translate easily.
Install Netbeans
Of course before you can get going, you need a proper Netbeans installation. Go to netbeans.org and download the "all" Netbeans package. During installation, make sure to install the bundled Glassfish V4.1 somewhere easy to find; you can disable the Tomcat installation if you want. My recommended Java development setup is the following directory structure. Adapt to your operating system of choice.- c:\dev\java\jdk8 - JDK installation folder
- c:\dev\java\netbeans8 - Netbeans installation folder
- c:\dev\java\glassfish4 - Glassfish installation folder
- c:\dev\java\projects - Where you will store your Netbeans projects
Now I'm not telling you how you should setup your development environment, I'm only giving an example and the rest of this article assumes the above setup is the truth. That makes it easier for you to reason how to adapt paths to your own choices and you really should setup according to your own taste. Just keep one thing in mind: it pays off to have installation paths without spaces in them; many tools tend to come with shell scripts, and not all shell scripts really cope well with spaces in paths. Having no spaces means you never have to tinker with quoting paths anywhere.
Create project
Creating the project is going to be almost a no-brainer. Choose File -> New Project. In the resulting dialog, choose Maven and then Project from Archetype as in the following screenshot.Click next, where we are going to search for the archetype com.airhacks; select javaee7-essentials-archetype in the search results, which is an archetype created by Adam Bien, as the groupId might suggest.
This archetype creates a barebones pom so you can compile everything JavaEE and setups both CDI and JAX-RS for you. Before that happens though, we have to click next and fill in some more paperwork. In the next step, fill in the projectname and the basic Maven data for your project (groupId, base application package name). Something like this:
No need to copy exactly what I used here, fill in what you're comfortable with. Not everything is set in stone either, you are free to pick a different groupId later for example by simply editing the pom.xml. The most important choice is the project location, put it where you don't lose it (and where you have write-access!). Click finish, and after you see some Maven-speak fly by in the console output, you will have a project.
Now as said, the archetype has created some files for us. Lets review them.
beans.xml
The beans.xml file as generated is simply this:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
</beans>
This is basically an empty file, but it is important that it exists as it is the trigger for the JavaEE container to go ahead and initialize CDI for this application of ours. Now this is less true in JavaEE7 containers as CDI will be enabled by default with or without this file, but it is still good practice to add this file anyway so you can configure at least the bean-discovery-mode property, and possibly deploy your application on a JavaEE6 container for testing purposes, if you have to. Unless you have compelling reasons, set the bean-discovery-mode to "all" so bean discovery works just like it did in JavaEE6 containers.
JAXRSConfiguration.java
@ApplicationPath("resources")
public class JAXRSConfiguration extends Application {
}
Another important class, this triggers the JavaEE container to setup RESTful webservices for us, and make our resources available under the url "/resources". Change the path to what you like. Also of course rename the com.airhacks package to whatever you need it to be (right click the package name, refactor -> rename). I will go ahead and rename it to gumby.showusers and I'll leave the default "resources" path as it is.
pom.xml
Nope, I'm not touching the Maven pom here. The reason being that it isn't really relevant, for this article Maven is basically abused to get a quick project setup going with a few clicks, and it is not being used for what it is really intended. We won't need to deal with Maven for the remainder of the article.Setting up Glassfish
As part of the Netbeans installation you should have installed a bundled Glassfish V4 server and parked it somewhere easy to find, say that c:\dev\java\glassfish4 directory I advised (or your operating system's equivalent). We can make that server available to our project by opening up the project properties (right click project name, properties). Under run, choose the server.That's all there is to it, Netbeans can now deploy our application to this server when you 'run' the project. However before we go there, lets add a datasource to the server in preparation for our database needs.
Adding a new JDBC driver
For demonstration purposes, I am going to be using HSQL for this test application and simply create an in-memory database, which is useful for application demonstration/prototype purposes. I choose HSQL because that is not something default available; Glassfish itself comes with Derby configured out of the box and if we wanted too we could use that and be on our way right away, but I wanted to add this extra step to show how it is done. If you want to go for a real database setup instead (and you should, eventually), later on this article I show how to setup MySQL in Glassfish.But first things first, we need to install a JDBC driver. This is as simple as downloading the jar from the Maven repositories and putting it in the directory GLASSFISH_DIR\glassfish\domains\domain1\lib, so in my setup example that would be c:\dev\java\glassfish4\glassfish\domains\domain1\lib. That's step 1 done.
Adding the datasource configuration
Now there are actually several ways to add a JDBC resource to the server; through Netbeans, although I couldn't get that to work at all and judging by posts on the internet, I am not the only one. You could use the Glassfish management web interface, but then you have to fill in icky text boxes. The easiest way possible is simply copy/paste programming; by adding XML configuration directly to the server configuration file. This configuration file is GLASSFISH_DIR\glassfish\domains\domain1\config\domain.xml. In this file, search for the xml element <resources>, under which you will find several pre-defined JDBC resources already, all derby resources. This is where we will be adding our application's new HSQL datasource and connection pool. Inside the <resources> element, add the following.
<resources>
... <!-- existing configuration here -->
<jdbc-connection-pool datasource-classname="org.hsqldb.jdbc.JDBCDataSource" name="SUPool" description="" res-type="javax.sql.DataSource"> <!-- [1] -->
<property name="DatabaseName" value="jdbc:hsqldb:mem:sudb"></property> <!-- [2] -->
<property name="User" value="SA"></property> <!-- [3] -->
<property name="Password" value=""></property>
</jdbc-connection-pool>
<jdbc-resource pool-name="SUPool" description="DataSource for Showusers" jndi-name="jdbc/sup"></jdbc-resource> <!-- [4] -->
</resources>
This small piece of configuration contains several key elements you should know about, and rename/change to your own needs.
- [1] - This is the pool configuration. The name can be anything, but you need to duplicate it in [4]. The datasource-classname must match the datasource class that your JDBC driver provides
- [2] - The database name in the case of HSQL is just the jdbc url. The url as specified here will make HSQL create an in-memory database.
- [3] - Username and password in case of HSQLDB are by default SA as the username and no password.
- [4] - here the jdbc resource is configured. The pool name must match the name of the pool you just created and the jndi-name is of importance too, we need that to be able to configure it in our application.
<servers>
<server config-ref="server-config" name="server">
... <!-- all predefined resource-ref elements here -->
<resource-ref ref="jdbc/sample"></resource-ref> <!-- this one already exists... -->
<resource-ref ref="jdbc/sup"></resource-ref> <!-- And this one you should add yourself -->
</server>
</servers>
Make sure the ref matches exactly the jndi-name you put in the jdbc-resource earlier (line [4]). And you're done!
Testing the configuration
At this point we can test out that we didn't bung it up by actually starting the server in Netbeans. Under the services tab you will find the servers, which holds the Glassfish server. Right-click it and select start to startup the server. When the little hourglass symbol disappears on the server the startup is complete, and at this point you can see deployed applications and resources under it. We have no applications yet, but if you unfold JDBC resources, you will see the JDBC resources we configured in the domain.xml earlier. the following cramped screenshot shows where the bits and bops are to take note of.Leave the server running, we'll need it again shortly.
Doing some JPA
We have our server up and running as we want now, so now we can actually do something with the database in our application. Since we're doing JavaEE here, of course we use JPA. As such, we need a persistence.xml file in our project in src/main/resources/META-INF. With the following content.
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="ShowusersPU" transaction-type="JTA"> <!-- [1] -->
<jta-data-source>jdbc/sup</jta-data-source> <!-- [2] -->
<properties>
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/> <!-- [3] -->
<property name="javax.persistence.schema-generation.create-source" value="metadata"/>
<property name="javax.persistence.schema-generation.drop-source" value="metadata"/>
</properties>
</persistence-unit>
</persistence>
- [1] - Define the persistence unit name (pick what you want) and the transaction-type. In a JavaEE application, just use JTA.
- [2] - The datasource; the value is the jndi-name that you configured in the server's domain.xml earlier, verbatim
- [3] - generation properties. What we setup here is to create tables automatically, from "metadata" rather than a script
The schema generation is well-suited for an in-memory database; tables will magically come to exist when the application is deployed, and they magically disappear when the application is stopped. The fact that tables are going to be generated based on meta data simply means that they are going to match the JPA entities you will create. One other thing you might notice about this persistence.xml is that it is completely generic; there is not a hint of any Hibernate or EclipseLink in there. And in any normal application there needn't be any, there will be one persistence provider only; the one provided by your container by default. You shouldn't need to care which one it is exactly, just use what is provided. Simple is better.
Adding an entity
Speaking of JPA entities, we need one if we are going to do anything at all with the database. Since our application is named showusers that is what we are going to do. Lets create an entity SuUser.
@Entity
public class SuUser implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String username;
private String password;
private String name;
private String email;
// no-arg constructor: mandatory to have for both JPA and JAX-RS
public SuUser() {
}
public SuUser(String username, String password, String name, String email) {
this.username = username;
this.password = password;
this.name = name;
this.email = email;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Nothing earth shattering about it, a basic user with a gigantic security hole since we are going to expose any password to the outside world willy-nilly in a second. I do like to demonstrate just how easily things can go wrong too. But I'm getting ahead of myself.
Creating fixture data
Having an entity is nice and dandy, but we wouldn't have any data in our magically created in-memory database. Nothing to worry, we're going to create fixture data, a nice strategy to have for prototype/demonstration applications. A simple singleton startup EJB can help us out immensely there.
@Startup
@Singleton
public class Fixtures {
@PersistenceContext
private EntityManager entityManager;
@PostConstruct
public void init(){
// setup fixtures
entityManager.persist(new SuUser("gumby", "gumby", "Gumby", "gumby@email.cm"));
entityManager.persist(new SuUser("you", "you", "You", "you@email.cm"));
}
}
As you can see, there is nothing inheritently CDI in this class; its all just old fashioned EJB 3.1 stuff. And why not? it works and you don't need to do crazy things like setting up a CDI producer for that EntityManager just to be able to inject it with the @Inject annotation. Just because CDI exists does not mean the old EJB API stuff is obsolete, far from it.
In any case, this little EJB will be invoked upon application startup once and will persist two users to our in-memory database. If you are anything familiar with EJBs and JavaEE technology at all this should be second nature to you; if this is the first time you're seeing EJB technology at work, I hope I have now tickled your fancy by showing you just how little code achieves so much.
Setting up a REST service to show the users
Finally, we've come to the point where we can go ahead and see the fruits of our labors. The easiest way imaginable is to just setup a REST service, arguably one of the most useful additions to the JavaEE platform imaginable. Lets create our UserResource.
@Path("users")
public class UserResource {
@PersistenceContext
private EntityManager entityManager;
@GET
public List<SuUser> all() {
List<SuUser> users = entityManager.createQuery("from SuUser u order by u.name").getResultList();
return users;
}
}
By the rules of the JAX-RS API, this will setup a resource for us under the path "/users". Since our application path was "/resources", the full RESTful url is "/resources/users". The default url will invoke our all() service which simply spits out the SuUser entity bean in the default output format, which is going to be JSON.
Lets recap before we test
At this point if you are new to all this material you might be a little lost where I put all the classes I just illustrated. Let me throw in a screenshot that shows what I did, but you can pick whatever package structure you are comfortable with.Test!
With all the files assembled, we can now right click the project and choose run to make Netbeans build and deploy the application as a war to the server. If everything is correct the Glassfish console log will show no errors and Netbeans will automatically open up a browser which will... show a 404. Oh no, did we do something wrong?The URL shown here may differ from yours, it will be showing the name of the application you picked during the project setup steps. Is our application perhaps not deployed? If we check the server in Netbeans...
Nope, there it is! (note: you may need to refresh the server to actually see the application appear there).
But no of course there is nothing wrong, Netbeans simply didn't point us to the proper url yet and expects us to have setup some webpages. Remember how the REST url mapping works, if we change the url to http://localhost:8080/showusers/resources/users, the result is a whole lot more satisfying. Keep your own application name of course.
Boom, our users dumped to the outside world in JSON format, complete with username and password. Isn't automation a great thing? In all seriousness: it is all too easy to just expose JPA entities through a RESTful webservice like this, but this may give you a hint as to why it may not be the best idea in the world; before you know it you expose your entire database automagically. This is a demonstration, not a set of design rules to live by :) Me personally I would expose only tailor-made value objects in RESTful services, and not ever expose JPA entities directly. Or if the data is really simplistic you can also just go ahead and return a JsonObject using the new JSON-P API, like so:
@GET
@Path("{id}")
public JsonObject getUser(@PathParam("id") int id) {
SuUser user = entityManager.find(SuUser.class, id);
return Json.createObjectBuilder().
add("username", user.getUsername()).
add("name", user.getName()).
build();
}
This sets up a REST service so we can get a specific user by ID, through the url "/resources/users/:ID", so say "/resources/users/1". But rather than dumping the entire SuUser entity, this manually crafts a JSON response object with only the username and the name property. Slightly more work, but ultimately a whole lot safer as adding a new column to the database and entity isn't going to magically expose it to the outside world.
Going real: setup MySQL
Of course in a real application you're not going to be using HSQL or any other in-memory database, you are going to be using a real database like Oracle, PostgreSQL or MySQL. So lets see what you need to do to setup a MySQL database. Very little, to be honest. If you have the HSQL example setup currently, I recommend you undeploy your application and clear the domains/domain1/generated folder. If you want to know why, investigate the solving problems section below.Step 1: Install driver
Put the MySQL Connector/J jar in the familiar domains/domain1/lib directory.
Step 2: Change the datasource
Here is the full setup, put them in the places where the earlier HSQL example illustrates:
<!-- in resources -->
<jdbc-connection-pool datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" name="YOURPOOLNAME" description="" res-type="javax.sql.DataSource">
<property name="URL" value="jdbc:mysql://localhost:3306/DATABASENAME"></property>
<property name="PortNumber" value="3306"></property>
<property name="DatabaseName" value="DATABASENAME"></property>
<property name="User" value="USERNAME"></property>
<property name="Password" value="PASSWORD"></property>
</jdbc-connection-pool>
<jdbc-resource pool-name="YOURPOOLNAME" description="DataSource for YOURAPPNAME" jndi-name="jdbc/YourApp"></jdbc-resource>
<!-- in servers -->
<resource-ref ref="jdbc/YourApp"></resource-ref>
Step 3: Tame the persistence.xml
Our persistence.xml as it currently stands works, but it is set to create and drop tables. We only want it to create tables in a physical database, so change it to the following:
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="YourAppPU" transaction-type="JTA">
<jta-data-source>jdbc/YourApp</jta-data-source> <!-- change to match domain.xml configuration -->
<properties>
<property name="javax.persistence.schema-generation.database.action" value="create"/> <!-- changed; use 'none' to disable schema generation -->
<property name="javax.persistence.schema-generation.create-source" value="metadata"/>
<property name="javax.persistence.schema-generation.drop-source" value="metadata"/>
</properties>
</persistence-unit>
</persistence>
Do note that I find it a bit fiddly to get EclipseLink to notice that it needs to auto-generate the schema. I can only really get it to work if I first fully undeploy the application from the server, clean the generated folder and then redeploy the application.
Step 4: tame the fixture generator At this point you may have switched out a database which is going to magically disappear for a database which is going to stick around. As such it isn't a good idea that our Fixtures class will insert data each and every time the application is started. We need to make it a tiny bit more clever, by only setting up fixtures if they aren't there yet already. A simple count query does the trick. This is just to stay in line with this article, if you are using a physical database it is more likely you have an existing database or SQL scripts to pre-fill tables and the Fixtures class is entirely irrelevant.
@Startup
@Singleton
public class Fixtures {
@PersistenceContext
private EntityManager entityManager;
@PostConstruct
public void init(){
int cnt = ((Number) entityManager.createQuery("select count(u) from SuUser u").getSingleResult()).intValue();
if(cnt == 0){
// setup fixtures, IF there is no data yet
entityManager.persist(new SuUser("gumby", "gumby", "Gumby", "gumby@email.cm"));
entityManager.persist(new SuUser("you", "you", "You", "you@email.cm"));
}
}
}
And that would be all really, if your MySQL database is up and running and the proper database and user is setup, deploy the app and see it work, hopefully.
Solving problems
Of course I make harsh claims about Glassfish being as good as any other JavaEE container - that is true, and thus it also has problems like any other JavaEE container. The more aggravating problems I ran into I will document here, and it greatly depends on which version of Netbeans you install too, as depending on the version of Netbeans you get a different version of Glassfish. At the time of writing two versions of Netbeans were available for download; 8.0.2 which comes with Glassfish 4.1 and 8.1.RC2 (release candidate 2, not an official build yet) which comes with Glassfish 4.1.1. Keep in mind that these problems are very much bound to the time period that the article was written; they may be irrelevant if you read this at a future date.Generic Glassfish problem: 'inconsistent module state' or 'javax.ejb.AccessLocalException: Client not authorized for this invocation'
The first problem we are discussing is one that has been reported since Glassfish 3 and apparently it is too difficult to properly fix it, as it still happens in version 4.1.1. This problem may happen to you when you are just starting out a project and you cause problems that make the deployment of your application blow up. When you fix said problems and you try to deploy your application again, Glassfish may suddenly throw up the exception Error in linking security policy for appname – Inconsistent Module State.If you google that error you will quickly find out that this is because when an error happens during deployment of the application, certain security policy files (partially) generated by Glassfish will not be properly deleted upon rolling back the application deployment, and will cause problems upon future deployments until removed and properly generated in full.
That is pretty much sh*t when you do automatic deployments from an IDE. The problem is not "that big" since eventually you will produce an application base which is stable and will properly deploy each and every time, but at the start of a project it can be a major annoyance. I have seen two basic ways to get rid of this error.
- 1. Undeploy application. Stop Glassfish. Start Glassfish - manually, do not start it by running your application. When the application is not deployed at server startup, Glassfish seems to go ahead and cleanup any generated files.
- At this point you can safely deploy your application and everything will be created fresh.
- 2. Manually delete the generated files. You can find them in GLASSFISH_DIR/glassfish/domains/domain1/generated. Do this when Glassfish is stopped.
There is also that second problem mentioned in the paragraph title: javax.ejb.AccessLocalException: Client not authorized for this invocation. This may seem like a security configuration issue, but no; it basically means that you made changes to an EJB and the data in the generated folder is out of date; which might happen relatively easy when you're coding away in Netbeans with the server turned off. The solution: manually clean the generated folder. Hence that I lump both errors together here.
TL;DR: Try to do as much of your development as possible with the server running - just let it redeploy. Historically that may give you cold chills as you may remember bad times of redeployments causing resources to leak. Give Glassfish a chance, I think you'll be surprised by how stable it is. It just makes your developer life easier if you let it do its thing.
Glassfish 4.1.1: java.lang.ClassNotFoundException: javax.xml.parsers.ParserConfigurationException
As said if you are running Netbeans 8.1.RC2 which comes with Glassfish 4.1.1, you follow this article and you try to invoke one of the RESTful webservice examples, you get the exception listed in the title. The full exception is java.lang.ClassNotFoundException: javax.xml.parsers.ParserConfigurationException not found by org.eclipse.persistence.moxy [ANY_NUMBER].You'd think that integration testing of the Glassfish server would have caught this. That's a problem with the version of EclipseLink (2.6.1-RC1) that is deployed with Glassfish 4.1.1 and will basically blow up any RESTful webservice you try to invoke in the default configuration. Currently there is no way around it as the Glassfish updater tool does not identify yet that there is a newer version of EclipseLink (but there is), so other than manually patching a newer version of EclipseLink into Glassfish which I do not know how to safely do, the only thing we can do is to apply the documented workaround of the bugreport covering this issue.
Step 1: go to the bugreport
The bugreport you can find here: EclipseLink bug ID 463169. You can read it, but its all a bit cryptic for people who are not on the EclipseLink development project. The key thing is the list of attachments in the issue, one of which is important to us.
Step 2: download attachment "manually edited manifest, added missing packages"
The issue has one attachment which holds a manually edited MANIFEST.MF file. It is not entirely clear from the issue for which jar exactly it is, but it turns out to be for the jar org.eclipse.persistence.moxy.jar, which you can find in the GLASSFISH_DIR/glassfish/modules directory.
Step 3: Replace MANIFEST.MF
Open up the org.eclipse.persistence.moxy.jar file in your favorite zip tool and navigate to the META-INF folder where you will find the MANIFEST.MF file. Replace this file with the one you downloaded in whatever way the zip tool allows you to do that (generally just dragging and dropping the file to the zip tool's window). Of course make a backup of the jar before you do that, just in case.
And that should do it, with the MANIFEST.MF file patched, you can start the server and your RESTful webservice should now work as it would when running Glassfish 4.1. Annoying that we have to patch something, but at least this is a one time thing and perhaps when Netbeans 8.1 releases officially, the bundled Glassfish 4.1.1 will already have been patched.
Glassfish 4.1.1: nullpointerexception in ServerPlatformUtils
The full error you may get is:Warning: java.lang.NullPointerException at org.eclipse.persistence.platform.server.ServerPlatformUtils.createServerPlatform(ServerPlatformUtils.java:99)This again is an EclipseLink 2.6.1 artifact and it seems to be a conflict with Glassfish 4.1.1 which is not reporting a proper server platform name. It is only a warning, it doesn't actually break anything. I have yet to find any way to make it go away so for the ugly exception is there to stay. It should be fixed in EclipseLink 2.6.2 / 2.7.0: EclipseLink Bug ID 463629.
JAX-RS in general: "No message body writer" for a simple POJO
This one had me stumped for a little while; I had a simple POJO class yet it could not be serialized to JSON. In the end I figured it out: I forgot to add the no-arg constructor to the POJO.Always add a no-arg constructor to any class that is going to be serialized.
Going real and solving problems: Payara
Okay Glassfish as bundled works. If you read around the internet you will not find much love for Glassfish as a production server. This has a few reasons, one being that it is a community product only - its free, and there is nothing more expensive than something that is free, especially in corporate environments. Glassfish is not as regularly updated as you would want it and response to hard bugs is community driven too, and for many people that is a problem.The answer to that problem is Payara, which is still free and open source - but it does receive regular updates, has responsive developers who really engage in the community and listen to bug reports and provides technical support options for those that need it. Payara itself is really just Glassfish in everything but name; you can plop it into Netbeans, set it up as a Glassfish server and you'll find everything where you will now expect to find it. But it has patches earlier and a more active following, and that is nice. Check it out for yourself: The Payara website.
In closing
That wraps it up for this Netbeans setup guide; you should now have all the tools you need to be able to get a proper working environment setup and take off with JavaEE development, without the head aches.If you are completely new to JavaEE technology you may want to know what was demonstrated here.
- JPA 2.1 - Online documentation
- EJB 3.1 - Online documentation
- JAX-RS 2 - API documentation
- JSON-P - Online documentation
- Glassfish 4.1 - Official site (with documentation and forum)