I am new to Java / Web and I was hoping someone here could help me.
I am creating a GAE application using Spring in Eclipse (Juno Windows 7). The project was generated using the Maven plugin for Eclipse (using Maven 3.1.0) and the appengine-maven module for Maven (using the GAE SDK 1.8.3).
Most of my messages should be sent via HTTPS, and I apply this in my Spring configuration. However, I do not understand how to configure the local DevAppServer to support HTTPS.
I started by creating a certificate
keytool -keystore myKeystore -genkey -keyalg RSA
which I hope to put on the server. However, GAE seems to work inside Jetty's own version, and it is unclear if I can change it.
I tried pushing it using command line arguments
<plugin> <groupId>com.google.appengine</groupId> <artifactId>appengine-maven-plugin</artifactId> <version>${appengine.target.version}</version> <configuration> <useJava7>true</useJava7> <address>127.0.0.1</address> <port>8080</port> <compileEncoding>utf-8</compileEncoding> <jvmFlags> <jvmFlag>-Xdebug</jvmFlag> <jvmFlag>-Xrunjdwp:transport=dt_socket,address=1044,server=y,suspend=y</jvmFlag> <jvmFlag>-Djavax.net.ssl.keyStore=C:\STEVEN-DEV\projects\apps\testserver\src\main\webapp\WEB-INF\myKeystore</jvmFlag> <jvmFlag>-Djavax.net.ssl.keyStorePassword=testpass</jvmFlag> </jvmFlags> </configuration> </plugin>
I know that the keystore is loading because I see exceptions if the path is wrong. However, Iβm not entirely sure that it is loading, and if thatβs even what I want to do.
When I debug an application from Eclipse, it appears in my logs after the application is packaged:
Running C:\Program Files\Java\jdk1.7.0_10\jre\bin\java -javaagent:C:\Users\Steven\.m2\repository\com\google\appengine\appengine-java-sdk\1.8.3\appengine-java-sdk\appengine-java-sdk-1.8.3\lib\agent\appengine-agent.jar -Xbootclasspath/p:C:\Users\Steven\.m2\repository\com\google\appengine\appengine-java-sdk\1.8.3\appengine-java-sdk\appengine-java-sdk-1.8.3\lib\override\appengine-dev-jdk-overrides.jar -Dappengine.fullscan.seconds=5 -classpath C:\Users\Steven\.m2\repository\com\google\appengine\appengine-java-sdk\1.8.3\appengine-java-sdk\appengine-java-sdk-1.8.3\lib\appengine-tools-api.jar -Xdebug -Xrunjdwp:transport=dt_socket,address=1044,server=y,suspend=y -Djavax.net.ssl.keyStore=C:\STEVEN-DEV\projects\apps\testserver\src\main\webapp\WEB-INF\myKeystore -Djavax.net.ssl.keyStorePassword=testpass com.google.appengine.tools.development.DevAppServerMain --allow_remote_shutdown -a 127.0.0.1 -p 8080 C:\STEVEN-DEV\projects\apps\testserver\target/testserver-0.0.1-SNAPSHOT
If I open chrome and try to access
https://localhost:8080/test/retval
I see "SSL connection error" and "Error code: ERR_SSL_PROTOCOL_ERROR"
If I try to switch to
http://localhost:8080/test/retval
I will be redirected to
https://localhost:8443/test/retval
and say "this webpage is not available."
Update 2:. Looking again at the docs, I found this
The development web server does not support HTTPS connections. This ignores the transport guarantee, so the paths intended for use with HTTPS can be tested using regular HTTP connections to the development website of the server.
So it seems that my problem is that my Spring configuration forces HTTPS. I can accept this and allow any type of connection. However, I'm not interested in doing this and would prefer a way to configure / hack the dev server to support SSL.
(Back to the old question: what I tried)
I do not know where my error is: GAE, Maven or Spring.
Below is my full pom.xml
I read the documentation online for hours. Any help would be greatly appreciated.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <groupId>com.steven</groupId> <artifactId>testserver</artifactId> <properties> <java.version>1.7</java.version> <maven.enforcer.plugin-version>1.3.1</maven.enforcer.plugin-version> <maven.version.range>[2.2.1,3.1.0]</maven.version.range> <appengine.app.version>1</appengine.app.version> <appengine.target.version>1.8.3</appengine.target.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <org.springframework-version>3.2.3.RELEASE</org.springframework-version> <org.springframework.security-version>3.1.4.RELEASE</org.springframework.security-version> <org.slf4j-version>1.7.5</org.slf4j-version> <ch.qos.logback-version>1.0.13</ch.qos.logback-version> <org.codehaus.jackson-version>1.9.12</org.codehaus.jackson-version> </properties> <dependencies> <dependency> <groupId>com.google.appengine</groupId> <artifactId>appengine-api-1.0-sdk</artifactId> <version>${appengine.target.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>com.google.appengine</groupId> <artifactId>appengine-testing</artifactId> <version>${appengine.target.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>com.google.appengine</groupId> <artifactId>appengine-api-stubs</artifactId> <version>${appengine.target.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${org.springframework-version}</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${org.springframework-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${org.springframework-version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>${org.springframework.security-version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>${org.springframework.security-version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>${org.springframework.security-version}</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>${org.codehaus.jackson-version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${org.slf4j-version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${org.slf4j-version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${ch.qos.logback-version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>${ch.qos.logback-version}</version> </dependency> </dependencies> <repositories> <repository> <id>springsource-repo</id> <name>SpringSource Repository</name> <url>http://repo.springsource.org/release</url> </repository> </repositories> <build> <pluginManagement> <plugins> <plugin> <groupId>org.eclipse.m2e</groupId> <artifactId>lifecycle-mapping</artifactId> <version>1.0.0</version> <configuration> <lifecycleMappingMetadata> <pluginExecutions> <pluginExecution> <pluginExecutionFilter> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <versionRange>[1.0.0,)</versionRange> <goals> <goal>enforce</goal> </goals> </pluginExecutionFilter> <action> <ignore /> </action> </pluginExecution> </pluginExecutions> </lifecycleMappingMetadata> </configuration> </plugin> </plugins> </pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <version>2.5.1</version> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.3</version> <configuration> <archiveClasses>true</archiveClasses> <webResources> <resource> <directory>${basedir}/src/main/webapp/WEB-INF</directory> <filtering>true</filtering> <targetPath>WEB-INF</targetPath> </resource> </webResources> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>${maven.enforcer.plugin-version}</version> <executions> <execution> <id>enforce-banned-dependencies</id> <goals> <goal>enforce</goal> </goals> <configuration> <rules> <bannedDependencies> <searchTransitive>true</searchTransitive> <excludes> <exclude>javassist:javassist</exclude> <exclude>commons-logging</exclude> <exclude>aspectj:aspectj*</exclude> <exclude>hsqldb:hsqldb</exclude> <exclude>log4j:log4j</exclude> <exclude>org.slf4j:[1.5, 1.6.5]</exclude> <exclude>org.springframework:2.*</exclude> <exclude>org.springframework:3.0.*</exclude> </excludes> </bannedDependencies> <requireMavenVersion> <version>${maven.version.range}</version> </requireMavenVersion> <requireJavaVersion> <version>${java.version}</version> </requireJavaVersion> </rules> <fail>true</fail> </configuration> </execution> </executions> </plugin> <plugin> <groupId>com.google.appengine</groupId> <artifactId>appengine-maven-plugin</artifactId> <version>${appengine.target.version}</version> <configuration> <useJava7>true</useJava7> <address>127.0.0.1</address> <port>8080</port> <compileEncoding>utf-8</compileEncoding> <jvmFlags> <jvmFlag>-Xdebug</jvmFlag> <jvmFlag>-Xrunjdwp:transport=dt_socket,address=1044,server=y,suspend=y</jvmFlag> <jvmFlag>-Djavax.net.ssl.keyStore=C:\STEVEN-DEV\projects\apps\testserver\src\main\webapp\WEB-INF\myKeystore</jvmFlag> <jvmFlag>-Djavax.net.ssl.keyStorePassword=testpass</jvmFlag> </jvmFlags> </configuration> </plugin> </plugins> </build> </project>
Update: I tried this with and without security restrictions in my web.xml
I cannot help but think that I need to find a way to configure the Jetty used by the plugin for the application to work with SSL
<?xml version="1.0" encoding="utf-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name>Test Server</display-name> <servlet> <servlet-name>mvc-dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc-dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/mvc-dispatcher-servlet.xml, /WEB-INF/spring-security.xml</param-value> </context-param> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <security-constraint> <web-resource-collection> <web-resource-name>test</web-resource-name> <url-pattern>/test/*</url-pattern> </web-resource-collection> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> </web-app>