I want to deploy a Java Netbeans Webapp with an embedded Jetty Server; the server itself works, but I always get the following error:
I searched through mounds of examples on the web, configured & reconfigured my web.xml; although my configuration seems fine, I can't get it to work.
I should point out, that when I run the app from whithin Netbeans using the built-in Glassfish server, it works fine, which tells me that web.xml is probably configured well.
Can anyone help with this?
My code follows.
P.S. I know that it's been asked on SO, but those examples did not work for me either.
Project structure:
WebContext setup:
import org.eclipse.jetty.webapp.WebAppContext;
public class AppContextBuilder {
private WebAppContext webAppContext;
public WebAppContext buildWebAppContext() {
webAppContext = new WebAppContext();
webAppContext.setDescriptor(webAppContext + "/WEB-INF/web.xml");
webAppContext.setResourceBase("src/main/webapp");
webAppContext.setContextPath("/Holmes");
return webAppContext;
}
}
JettyServer.java:
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
public class JettyServer {
private Server server;
public JettyServer() {
this(8585);
}
public JettyServer(Integer runningPort) {
server = new Server(runningPort);
}
public void setHandler(ContextHandlerCollection contexts) {
server.setHandler(contexts);
}
public void start() throws Exception {
server.start();
}
public void stop() throws Exception {
server.stop();
server.join();
}
public boolean isStarted() {
return server.isStarted();
}
public boolean isStopped() {
return server.isStopped();
}
}
Deploy.java (main method):
import org.apache.log4j.Logger;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
/**
*
* #author Motty Waldner <motty#timeworksny.com>
*/
public class Deploy {
private final static Logger log = Logger.getLogger(Deploy.class);
static JettyServer jettyServer = new JettyServer();
public static void main(String[] args) throws Exception {
// add hook to stop server upon service termination
// (service calls System.exit(0) upon termination,
// so it should work under normal circumstances)
addShutdownHook();
ContextHandlerCollection contexts = new ContextHandlerCollection();
Handler[] handlers = new Handler[]{new AppContextBuilder().buildWebAppContext().getHandler()};
contexts.setHandlers(handlers);
jettyServer = new JettyServer();
try {
jettyServer.start();
} catch (Exception e) {
log.error("Error Starting Jetty Server", e);
}
}
private static void addShutdownHook() {
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
try {
jettyServer.stop();
log.info("Shutdown Hook is running: Jetty Server instance being stopped.");
} catch (Exception e) {
log.error("error", e);
}
log.info("Application Terminating ...");
}
});
}
}
Web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Test App</display-name>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name> struts2 </filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<session-config>
<session-timeout>120</session-timeout>
</session-config>
<servlet-mapping>
<servlet-name>StrutsController</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
</web-app>
Thanks in advance for the help!
Is there any stack trace logs available?
Without more logs, I can only imagine based on experience that it may be caused by directory resolving, it worked fine in your IDE since it can find the proper files without any further context configuration staff ,which may be not the case when you carry out a real deployment.
Maybe the url-pattern is wrong, try to change to something like:
<servlet-mapping>
<servlet-name>StrutsController</servlet-name>
<url-pattern>*</url-pattern>
</servlet-mapping>
change from
public class AppContextBuilder {
private WebAppContext webAppContext;
public WebAppContext buildWebAppContext() {
webAppContext = new WebAppContext();
webAppContext.setDescriptor(webAppContext + "/WEB-INF/web.xml");
webAppContext.setResourceBase("src/main/webapp");
webAppContext.setContextPath("/Holmes");
return webAppContext;
}
}
to
public class AppContextBuilder {
private WebAppContext webAppContext;
public WebAppContext buildWebAppContext() {
webAppContext = new WebAppContext();
webAppContext.setDescriptor(webAppContext + "/WEB-INF/web.xml");
webAppContext.setResourceBase(webAppContext);
webAppContext.setContextPath("/Holmes");
return webAppContext;
}
}
try this one let me know
Change
Handler[] handlers = new Handler[]{new AppContextBuilder().buildWebAppContext().getHandler()};
to
Handler[] handlers = new Handler[]{new AppContextBuilder().buildWebAppContext()};
Related
I have a working java 7 app that runs on tomcat 7 and MYSQL. I am trying to get it running on the basic (free tier) platform offered by Amazon AWS. I have succesfully loaded data to the RDS instance of MYSQL Community and set up an Elastic Beanstalk instance where basic JSPs are running correctly.
I am new to AWS so main problem should be my lack of knowledge.
I am not able to connect to the database from my code.
This is the code I am using to create the connection pool:
package com.authz.pap;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class DBConnections {
private static DataSource dataSource;
private static final DBConnections instance = new DBConnections();
static
{
try
{
Context c = new InitialContext();
dataSource = (DataSource)c.lookup("java:comp/env/jdbc/authzDB");
}
catch (Exception e)
{
dataSource = null;
}
}
private DBConnections()
{
}
public static DBConnections getInstance()
{
return instance;
}
public static DataSource getGeoServDS() {
//if(dataSource==null) instance = new DBConnections();
return dataSource;
}
}
And this:
public DbCon() {
conn=null;
ProcessStatus stat = new ProcessStatus();
stat.function="DbCon.DbCon";
stat.message = "Initializing DB";
stat.retcode=0;
stat.record();
try {
conn=DBConnections.getGeoServDS().getConnection();
conn.setAutoCommit(false);
} catch (Exception e) {
stat.message = e.toString();
stat.retcode=-1;
stat.record();
}
}
And this is the content of the context.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/rest">
<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" maxActive="8" maxIdle="4" name="jdbc/authzDB" password="xxxx" type="javax.sql.DataSource" url="jdbc:mysql://x.x.x.x:3306/authzDB?autoReconnect=true&allowMultiQueries=true" username="root"/>
<ResourceLink global="jdbc/authzDB" name="jdbc/authzDB" type="javax.sql.DataSource"/>
</Context>
What I get is a java.lang.NullPointerException on DB initialization.
What am I doing wrong?
UPDATE:
This is the content of the web.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" id="WebApp_ID" version="2.5">
<display-name>paprest</display-name>
<servlet>
<servlet-name>PAP rest interface</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.authz.pap.intfc</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest interface</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Double response:
1- I have not been able to use the data from context.xml file. I have ised a different solution:
private static Connection getRemoteConnection() {
ProcessStatus stat = new ProcessStatus();
try {
Class.forName("com.mysql.jdbc.Driver");
String dbName = "xxxxDB";
String userName = "xxxxx";
String password = "xxxxxx";
String hostname = "xxxxxxxx";
String port = "3306";
String jdbcUrl = "jdbc:mysql://" + hostname + ":" + port + "/" + dbName + "?user=" + userName + "&password=" + password + "&autoReconnect=true&allowMultiQueries=true";
Connection con = DriverManager.getConnection(jdbcUrl);
return con;
}
catch (ClassNotFoundException e) { stat.error(e.toString());}
catch (SQLException e) { stat.error(e.toString());}
return null;
}
2- I had a different problem, as the RDS instance is not to be created independently but related to the Elastic Beanstalk. This allows the comunication betwen tomcat and Mysql.
I'm trying to create a Jersey Resource that allows me to reuse an ElasticSearch TransportClient. So I would like to use a single instance of TransportClient over all Resources that require it. So far I've got this:
Resource:
#Path("/request")
public class ConfigurationResource {
private final TransportClient transportClient;
#Inject
public ConfigurationResource(TransportClient transportClient)
{
this.transportClient = transportClient;
}
#GET
#Produces(MediaType.TEXT_PLAIN)
public String AlarmStatus(){
if(transportClient != null)
return "Not NULL! ID: ";
else
return "NULL :(";
}
}
Binding:
public class WebMainBinder extends AbstractBinder {
#Override
protected void configure() {
TransportClient transportClient = null;
try {
transportClient = TransportClient.builder().build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
} catch (UnknownHostException e) {
e.printStackTrace();
return;
}
bind(transportClient).to(TransportClient.class);
}
}
Main Application:
#ApplicationPath("service")
public class WebMain extends ResourceConfig {
public WebMain(){
register(new WebMainBinder());
packages(true, "com.eniacdevelopment.EniacHome.Resources");
}
}
Web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>com.eniacdevelopment.EniacHome.Application.WebMain</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>com.eniacdevelopment.EniacHome.Application.WebMain</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
</web-app>
I've also tried using a factory like so:
public class TransportClientFactory implements Factory<TransportClient> {
private TransportClient transportClient;
#Override
public TransportClient provide() {
if(this.transportClient == null){
try {
transportClient = TransportClient.builder().build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
} catch (UnknownHostException e) {
e.printStackTrace();
return null;
}
}
return transportClient;
}
#Override
public void dispose(TransportClient transportClient) {
}
}
And then binding it this way:
bindFactory(TransportClientFactory.class)
.to(TransportClient.class).in(Singleton.class);
But no success. I keep on getting Unsatisfied dependencies for type TransportClient with qualifiers #Default.
Help would be much appreciated!
I've found Jersey's DI container functionality pretty unpleasant. I prefer to use Guice for managing my DI, so if you're open to using Guice, you can see how to wire up Jersey and Guice to collaborate in this demo project: https://bitbucket.org/marshallpierce/guice-jaxrs-examples. The common subproject has the shared logic, and there are other subprojects for the jersey and resteasy specific parts.
Alright got it to work:
When I at first tried to deploy the app to glassfish it complained about some guava dependency. I swapped the Guava jar in glassfish/modules with the one maven had installed and got it to deploy. It may have something to do with that. No guarentees here.
I decided to drop the whole glassfish stuff and start from scratch. On the jersey introduction page there's this maven archetype that can be isntalled like so:
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.24
Starting from there helped me out.
I'm trying a self-executable WAR package with Jetty. It configures with web.xml by default. If a run-time option is given, I wanted to override web.xml by Java code-level configuration with ServletContextHandler#addServlet, #addEventListener, and ...
Can I ignore web.xml while loading a WAR package?
% java -jar foobar.jar # Use web.xml
% java -jar foobar.jar --customize=something # Use Java code to configure
// Example
WebAppContext webapp = new WebAppContext();
webapp.setWar(warLocation.toExternalForm());
webapp.setContextPath("/");
if ( /* has run-time options */ ) {
webapp.setWar(warLocation.toExternalForm()); // But, no load web.xml!
// Emulates web.xml.
webapp.addEventListener(...);
webapp.setInitParameter("resteasy.role.based.security", "true");
webapp.addFilter(...);
} else {
webapp.setWar(warLocation.toExternalForm()); // Loading web.xml.
}
Additional Question:
Before server.start() is called, classes under WEB-INF/ are not loaded. Can I do some configuration webapp.something() with some classes under WEB-INF/? (E.g. extend WebInfConfiguration or do a similar class-loading that WebInfConfiguration does?)
For example, I'd like to do something like:
webapp.addEventListener(new SomeClassUnderWebInf()));
webapp.addEventListener(someInjector.inject(SomeClassUnderWebInf.class));
before server.start().
Handle the WebAppContext Configuration yourself.
Eg:
private static class SelfConfiguration extends AbstractConfiguration
{
#Override
public void configure(WebAppContext context) throws Exception
{
// Emulates web.xml.
webapp.addEventListener(...);
webapp.setInitParameter("resteasy.role.based.security", "true");
webapp.addFilter(...);
}
}
public static void main(String[] args) throws Exception
{
Server server = new Server(8080);
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/");
if (useWebXml)
{
webapp.setConfigurationClasses(WebAppContext.getDefaultConfigurationClasses());
}
else
{
webapp.setConfigurations(new Configuration[] {
new SelfConfiguration()
});
}
webapp.setWar("path/to/my/test.war");
webapp.setParentLoaderPriority(true);
server.setHandler(webapp);
server.start();
server.join();
}
I cloned servlet:
https://github.com/eHarmony/vw-webservice . I want to start this servlet from my jetty code. I am using guice to add classes to jetty. It looks like I need to move applicationContext so it works as a jar, not war . I don't have experience with jetty or spring. I would love to hear what you think about it.
GuiceConfig.java
public class GuiceConfig extends GuiceServletContextListener
{
#Override
protected Injector getInjector()
{
return Guice.createInjector(new JerseyServletModule() {
#Override
protected void configureServlets() {
bind(ClassThatProcessRequest.class);
bind(InjecteeInterface.class).to(Injectee.class);
serve("/*").with(GuiceContainer.class);
}
});
}
}
and main.java
public class Main {
public static void main(String[] args) throws Exception {
Server server = new Server(8080);
ServletContextHandler root = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
root.addEventListener(new GuiceConfig());
root.addFilter(GuiceFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
root.addServlet(EmptyServlet.class, "/*");
server.start();
}
}
When I start server I get
com.google.inject.CreationException: Guice creation errors:
No implementation for com.eharmony.matching.vw.webservice.core.exampleprocessor.ExampleProcessorFactory was bound.
here is applicationContext.xml and web.xml
https://github.com/eHarmony/vw-webservice/blob/master/vw-webservice-jersey/src/main/webapp/WEB-INF/applicationContext.xml
https://github.com/eHarmony/vw-webservice/blob/master/vw-webservice-jersey/src/main/webapp/WEB-INF/web.xml
I have created RPC service in my existing application using the RPC tutorial mentioned on the page
http://www.gwtproject.org/doc/latest/tutorial/RPC.html#services. I am still getting the 404 no service found exception. Here is what I have done.
Created the service interface on client side.
#RemoteServiceRelativePath("searchportoutorder")
public interface SearchPortOutOrderService extends RemoteService {
List<SearchPortOutOrderModel> fetchMoreRecords();
}
Created the asynce interface on client.
public interface SearchPortOutOrderServiceAsync {
void fetchMoreRecords(AsyncCallback<List<SearchPortOutOrderModel>> async);
}
Create the service impl under package server.
public class SearchPortOutOrderServiceImpl extends RemoteServiceServlet implements SearchPortOutOrderService {
List<SearchPortOutOrderModel> models = new ArrayList<SearchPortOutOrderModel>();
private void initializeModel() {
for(int i=0;i<10000;i++){
SearchPortOutOrderModel model = new SearchPortOutOrderModel();
model.setOrderId("1234-132131-12312-12312");
model.setCustomer("ashish testing");
model.setOrderDate("2014-12-25");
model.setLastUpdated("2014-02-15");
model.setStatus("Completed");
models.add(model);
}
}
#Override public List<SearchPortOutOrderModel> fetchMoreRecords() {
initializeModel();
return models;
}
Update the web.xml file to involve the servlet.
<servlet>
<servlet-name>searchPortOutOrderService</servlet-name>
<servlet-class>com.inetwork.gwt.client.searchportoutorder.server.SearchPortOutOrderServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>searchPortOutOrderService</servlet-name>
<url-pattern>/report/searchportoutorder</url-pattern>
</servlet-mapping>
I am still getting 404 exception saying that the service is not found.Do I need to modified anything else in my code like .gwt.xml file.
if your gwt module name is not report
modify *.gwt.xml like this.
<module rename-to='report'>
or replace url-pattern in web.xml to your gwt-module-name.