I know you can build a WAR file to deploy to an application server, but what kind of server is created when you run the main Application class?
/**
* Main method, used to run the application.
*/
public static void main(String[] args) throws UnknownHostException {
SpringApplication app = new SpringApplication(Application.class);
SimpleCommandLinePropertySource source = new SimpleCommandLinePropertySource(args);
addDefaultProfile(app, source);
Environment env = app.run(args).getEnvironment();
log.info("Access URLs:\n-----------------------------------------------------\n\t" +
"Local: \t\thttp://127.0.0.1:{}\n\t" +
"External: \thttp://{}:{}\n-----------------------------------------------",
env.getProperty("server.port"),
InetAddress.getLocalHost().getHostAddress(),
env.getProperty("server.port"));
}
By default Spring Boot uses Tomcat. You can configure it to use Jetty or Undertow as embedded container. You can check your pom.xml and see if there are any references to them. If not, you can assume, it is Tomcat
After version of 3.7.0 JHipster migrated to Undertow. The release note says:
Migration to Undertow is our biggest change - see #4054. This brings some very good performance enhancements in start up time and memory usage: this is good for everyone, but people doing microservices will benefit from it even more. With this change, JHipster uses nearly as much JBoss code (Undertow, Hibernate, Bean Validation, MapStruct) as Spring code!
For more information visit here
Related
I have my endpoints like so:
#Path("/users")
public class Users {
private final SomeDependency dependency
public Users(SomeDependency dependency) {
this.dependency = dependency;
}
#GET
#Path("/{id}")
public Response Get(#PathParam("id") int id) {
User user = this.dependency.get(id);
return Response.ok(user).build();
}
}
Now how do I actually run a server with this endpoint?
I am confused about web servers/applications/servlets, using jersey jetty glassfish or whatever. Also web.xml files? what? ResourceConfigs only accept classes, not their instances. Everything seems to be such a mess.
How can I just do something similar to this?
public static void main(String[] args) throws Exception {
SomeDependency dependency = new SomeDependency();
Users usersEndpoint = new Users(dependency);
Server server = new Server();
server.registerEndpoint(usersEndpoint);
server.start();
}
Server
As far as the server goes, you have two types you have to consider: installed or embedded.
Installed
An installed server is one that is installed on your machine. For example, if you download Tomcat 10 and then follow the installation instruction, the server will get installed on your machine at whatever location you choose. In this situation, when you have an app (a war file) you are ready to deploy, you will copy it to your Tomcat server (to a specific location) and on server startup, Tomcat will see the application and then run it. The applications running in this type of environment will require a web.xml as they are deployed in a war file.
Embedded
An embedded server is one that is packaged into your jar application and is started in a main method just like any other Java SE application. Most installed servers also come with an embedded version. All you need to do is add the server dependencies into your application and then write the server configuration and startup (and shutdown) code. Applications running in this environment will not require a web.xml as they are deployed as a jar file.
Which one to use?
With the advancement and popularity of cloud services and microservices, many applications are moving towards embedded servers. The reason is that they are easy to deploy, are scalable, relatively lightweight, and applications become more self contained. There are many other pros that come with using embedded servers, but there are also some cons. Do your research before you make your final decision about which one you should use.
Example
If you want to quickly get started without having to worry about setting up the project, knowing what dependencies you need to add, adding the startup code, an easy way to get up and running is to use a Maven Archetype. If you go to the Jersey Docs, they get you started with an embedded Grizzly server running a Jersey application. What you need to do is run the following command from the command line (assuming you have Maven installed in your machine)
mvn archetype:generate -DarchetypeArtifactId=jersey-quickstart-grizzly2 \
-DarchetypeGroupId=org.glassfish.jersey.archetypes -DinteractiveMode=false \
-DgroupId=com.example -DartifactId=simple-service -Dpackage=com.example \
-DarchetypeVersion=2.33
If you read the docs I linked to, it will give an explanation of all that comes with the initial application. The main class will look like the following (with comments and imports omitted)
public class Main {
public static final String BASE_URI = "http://localhost:8080/myapp/";
public static HttpServer startServer() {
final ResourceConfig rc = new ResourceConfig().packages("org.example");
return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
}
public static void main(String[] args) throws IOException {
final HttpServer server = startServer();
System.out.println(String.format("Jersey app started with WADL available at "
+ "%sapplication.wadl\nHit enter to stop it...", BASE_URI));
System.in.read();
server.stop();
}
}
In this code, they use the packages() method of the ResourceConfig class that specifies a package for Jersey to scan for #Path and #Provider classes to register. In your case, if you don't need that, you can remove the method call. If you want to register your Users instance, all you do is call register(users) on the ResourceConfig.
See Also
What exactly is the ResourceConfig class in Jersey 2 - this link will help you get started with the ResourceConfig class and show you how you can register you resource classes or instances.
Other Frameworks
There are other frameworks out there that you may also want to consider
Dropwizard - Dropwizard is an opinionated framework built on top of Jersey. It uses an embedded Jetty as its server and comes with many other features to make developing your applications easier. They have pretty good, easy to follow documentation. There is a good "getting started" guide if you want to give them a try.
Spring Boot - Spring Boot is a bootstrapping framework that makes getting up and running with applications much easier. There are auto configurations made for you but give you options to change them. You can use Spring MVC or Jersey as the REST framework when you work with Spring Boot. There is also an Initializer, which is similar to the Maven Archetypes, but is interactive and allows you to add what you want to your applications.
So I just accepted the fact that java is an utter mess and pulled these dependencies in:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.4.2</version>
</dependency>
So i can launch everything like so:
public static void main(String[] args) throws Exception {
SomeDependency dependency = new SomeDependency();
Users usersEndpoint = new Users(dependency);
JAXRSServerFactoryBean serverFactory = new JAXRSServerFactoryBean();
serverFactory.setResourceClasses(usersEndpoint.getClass());
serverFactory.setResourceProvider(usersEndpoint.getClass(), new SingletonResourceProvider(usersEndpoint));
serverFactory.setAddress("http://localhost:8080/");
serverFactory.create().start();
}
I have more endpoints, of course, so I put everything in a for loop.
As to why I'm answering from a guest account, the account I used to ask this question was created using a disposable email address, and I can no longer access it.
Hope this helps anyone in the future!
I built a simple Java web application. It provides a series of RESTful APIs for the user to carry out certain operations on a Java DB through a web interface. I used NetBeans environment during the development, and Glassfish for testing.
Now that I finished it, I would like to be able to deploy it on another machine using binaries (although as for now I use the same machine until I learn how to do it).
I installed Tomcat 7, and moved the .war file into Tomcat's webapp folder. The application deploys. Thereafter I try to read some data from the databse using a button I created just for this, but get the following error
I am not sure what went wrong, but I have two theories.
1) The web application cannot connect to the database. Yet when I attempted to run the application again, after starting JavaDB from NetBeans, there was no difference.
2) Somehow, the application cannot reach the Node service. I assumed that there will be no need to change the API links while moving the app, but perhaps I was wrong.
Or maybe there is some other issue I did not consider? I will be grateful for any advice about how to properly deploy such an application.
EDIT: The issue was solved by using TomEE.
The error is come from your application server of choice.
TomCat is only a servlet container (means it only support Servlet/JSP).
Any other feature (JAX-RS, CDI etc) require a Java EE certified server e.g. GlassFish, WildFly,Payara, WebLogic, OpenLiberty or TomEE.
TomEE could be your best bet if you want to use TomCat in your production or test environment, it is basically TomCat + Java EE other feature.
EDIT:
TomEE don't have a GUI for JNDI datasource configuration like GlassFish, you need to edit conf/tomee.xml
<Resource id="myDataSource" type="javax.sql.DataSource">
jdbcDriver = org.apache.derby.jdbc.ClientDriver
jdbcUrl = jdbc:derby://localhost:1527/dbname
userName = app
password = app
</Resource>
And in your java code:
#Path("resources")
#Stateless
public class MyResources{
#Resource(name="myDataSource")
DataSource dataSource;
#GET
public Response SomeMethod(){
//Do stuff here
}
}
You can check here for more detail configuration on data source.
I have a Spring boot web application running on Production deployed on Amazon Web Servers. I have create two instances of my Web applications. But sometimes one/both instance(s) automatically stops. I can't understand how the process are killed automatically.
This issue is affecting many users experience. I am using Spring Boots default properties for tomcat.
Check your application.properties for endpoints.shutdown.enabled=true.
Perhaps the shutdown endpoint is getting called by someone.
Also, scan your code for any 'System.exit'
Also, the jvm may be crashing...
Is it stopping gracefully? Are there any logs?
Found the problem:
springBoot {
mainClass = ''
executable = true
buildInfo()
}
executable needs to be changed to false
I have jbossesb-server-4.11 and eclipse-jee-juno.
I want to create some simple EJB application, deploy it on server and call some method from client. Everything seems to be clear.
I have found a simple Hello world application here: https://sites.google.com/a/thedevinfo.com/thedevinfo/Home/jboss/jboss-application-server/ejb3-session-bean-tutorial-using-jboss-and-eclipse.
I did all the same, I also tried to download this example from this site but it does not work for me.
I created JBoss server in Eclipse, then I run my ejb application on this server, then I tryied to get my bean this way:
InitialContext ctx = new InitialContext(props);
MyBeanRemote bean = (MyBeanRemote) ctx.lookup("MyBean/remote");
But i have the following error: "javax.naming.NameNotFoundException: MyBean not bound".
Here is my simple code in ejb project:
#Remote
public interface MyBeanRemote extends IMyBean{}
#Local
public interface MyBeanLocal extends IMyBean {}
#Stateless
public class MyBean implements MyBeanLocal, MyBeanRemote {
public void doSomething() {
System.out.println("Hello World!");
}
}
Please advice me where I am wrong?
It looks like standalone jbossesb-server is very narrowly specialized product. It provides ESB-specific functionality but lacks EJB support.
Your test app deploys and runs fine on vanilla JBossAS 4.2.3.GA though (AS 4.2.3 is the foundation for jbossesb-server-4.11 I think).
If ESB is a must for you, I recommend installing JBoss ESB as an extension for plain JBoss 4.2.3.GA or maybe newer 5.x, 6.x series (AFAIK 7.x is not supported yet). In order to do so you need to download jboss-4.2.3.GA and jbossesb-4.11.zip instead of jbossesb-server-4.11.zip. Then you need to follow this instructions.
Pay attention there are two editions of JBossAS 4.2.3:
jboss-4.2.3.GA.zip - for JDK5
jboss-4.2.3.GA-jdk6.zip - for JDK6+
the same is true for 5.x series (6.x and 7.x require JDK6+).
The other option is using full commercial SOA solution: RedHat's SOA Platform. It's not cheap though.
I have written unit tests for several session beans I have created. When I try to run them, however, NetBeans gives me the following error:
No EJBContainer provider available. The following providers: org.glassfish.ejb.embedded.EJBContainerProviderImpl returned null from createEJBContainer call.
I highly suspect that this is the root cause of the issue:
SEVERE: EJB6004:Specified application server installation location [C:\Development\GlassFish\3.1\glassfish\domains\domain1] does not exist.
It's right. Domain1 does not exist. I created a "development" domain myself and deleted domain1 but it seems there is a lingering reference of which I have no clue where to modify it. The non-embedded container the embedded container is referring to is registered in NetBeans as well and correctly hooked up to the development domain. There are no problems with regular deployments of the project.
Any help very much appreciated!
I believe ScatteredWar is outdated. After a bunch of searching I found the incredibly helpful post Quick introduction to Embeddability of GlassFish Open Source Edition 3.1, which gives this snippet:
If your archive is not pre-built, instead it's components are scattered in multiple directories, then you may be interested in using the scattered archive APIs:
import org.glassfish.embeddable.;
import org.glassfish.embeddable.archive.;
Deployer deployer = glassfish.getDeployer();
// Create a scattered web application.
ScatteredArchive archive = new ScatteredArchive("testapp", ScatteredArchive.Type.WAR);
// target/classes directory contains my complied servlets
archive.addClassPath(new File("target", "classes"));
// resources/sun-web.xml is my WEB-INF/sun-web.xml
archive.addMetadata(new File("resources", "sun-web.xml"));
// resources/MyLogFactory is my META-INF/services/org.apache.commons.logging.LogFactory
archive.addMetadata(new File("resources", "MyLogFactory"), "META-INF/services/org.apache.commons.logging.LogFactory");
deployer.deploy(archive.toURI())
Other docs: Oracle GlassFish Server 3.1 Embedded Server Guide and The updated API.
Adam Bien and Arun Gupta speak about ways to embed GlassFish for unit testing.
The main piece is this:
GlassFish glassfish = new GlassFish(port);
ScatteredWar war = new ScatteredWar(NAME,
new File("src/main/resources"),
new File("src/main/resources/WEB-INF/web.xml"),
Collections.singleton(new File("build/classes").toURI().toURL()));
glassfish.deploy(war);
An alternative approach would be to use OpenEJB to do your unit testing, as this will ensure that you're sticking to standards. Adam as has has an entry on setting that up.