I'd like to control which public IP addresses my app can connect to, so that I can blacklist a small set of IPs for outgoing connections for the entire app.
Deploying a Tomcat Java app to Heroku, I've specified a custom Java security configuration by overriding "java.security.properties"
web: java $JAVA_OPTS -Djava.security.properties=java.security -jar target/dependency/webapp-runner.jar --port $PORT target/*.war
In that config, I've given a custom SSLSocketFactory class
ssl.SocketFactory.provider=security.MyCustomSocketFactory
This allows MyCustomSocketFactory to examine every IP address and host for outgoing connections in a small sample app. However, it's not working for my full application after I deploy to Heroku. The class isn't found, even though it is packaged into the .war file.
Caused by: java.lang.ClassNotFoundException: security.MyCustomSocketFactory
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
at java.base/javax.net.ssl.SSLSocketFactory.getDefault(SSLSocketFactory.java:105)
at java.base/javax.net.ssl.HttpsURLConnection.getDefaultSSLSocketFactory(HttpsURLConnection.java:335)
at java.base/javax.net.ssl.HttpsURLConnection.<init>(HttpsURLConnection.java:292)
I think I have to specify that my single class is class-loaded differently, because my application is initialized by webapp-runner.jar. Is there a different approach I should be taking?
I know my class is available to some classloader, because I can call Class.forName() from my own code, without getting an exception. But it's just not able to be loaded from SSLSocketFactory.getDefault().
As codefinger suggested in a comment, I needed to include MyCustomSocketFactory on the classpath outside of the war file.
I moved MyCustomSocketFactory to a separate Maven project, and built it as a separate jar.
Then, I added a built step on my main project to copy the JAR into the same directory as webapp-runner.jar.
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-socketblocker</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/dependency</outputDirectory>
<resources>
<resource>
<directory>jars</directory>
<includes>socketblocker-1.0.jar</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Finally, I modified my Procfile to use wildcard matching, and add both webapp-runner.jar and my custom JAR as classpath entries.
web: java $JAVA_OPTS -Djava.security.properties=java.security -cp "target/dependency/*" webapp.runner.launch.Main --port $PORT target/*.war
I use the jetty-maven-plugin for local development testing. What I want is from a single jetty:run command, start a bunch of jetty containers on separate ports as specified in the pom.xml -- I don't want to specify it within the war. My current plugin configuration block looks like ::
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<contextHandlers>
<contextHandler implementation="org.eclipse.jetty.webapp.WebAppContext">
<war>${basedir}/service-a/target/a.war</war>
<contextPath>/a</contextPath>
<allowNullPathInfo>true</allowNullPathInfo>
</contextHandler>
<contextHandler implementation="org.eclipse.jetty.webapp.WebAppContext">
<war>${basedir}/service-b/target/b.war</war>
<contextPath>/b</contextPath>
<allowNullPathInfo>true</allowNullPathInfo>
</contextHandler>
</contextHandlers>
</configuration>
I know I can specify a -Djetty.port but that globally sets the port. The above example starts both wars in the same jetty container instance running on port 8080. Does anyone know a switch within contextHandler to set the port or how to do it if I have multiple instances of the entire plugin block? Every example I've searched for only has the option to set it in the jetty.xml file within the war which I don't want to do.
It's possible if you name the connectors and context handlers
<configuration>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>8080</port>
<name>instance_8080</name>
</connector>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>8081</port>
<name>instance_8081</name>
</connector>
</connectors>
<contextHandlers>
<contextHandler implementation="org.eclipse.jetty.webapp.WebAppContext">
<war>${basedir}/service-a/target/a.war</war>
<contextPath>/a</contextPath>
<connectorNames>
<item>instance_8080</item>
</connectorNames>
</contextHandler>
<contextHandler implementation="org.eclipse.jetty.webapp.WebAppContext">
<war>${basedir}/service-b/target/b.war</war>
<contextPath>/b</contextPath>
<connectorNames>
<item>instance_8081</item>
</connectorNames>
</contextHandler>
</contextHandlers>
</configuration>
Note, this configuration is for org.mortbay.jetty:jetty-maven-plugin.
In your jetty maven plugin you can create multiple connectors that can run on different ports. That's a first start.
I'm not sure offhand how or if those connector blocks can run different wars. They can refer to different jetty.xml (although I've had nothing but trouble with jetty.xml)
http://www.eclipse.org/jetty/documentation/current/jetty-maven-plugin.html#configuring-jetty-container
I have a maven project where java stubs are generated from wsdl files using axistools-maven-plugin.
Within pom we have following:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>axistools-maven-plugin</artifactId>
<version>${axistools-maven-plugin.version}</version>
<configuration>
<mappings>
<mapping>
<namespace>xyz</namespace>
<targetPackage>x.y.z</targetPackage>
</mapping>
<mapping>
<namespace>http://time.joda.org</namespace>
<targetPackage>com.org.joda.time</targetPackage>
</mapping>
<mapping>
<namespace>abc</namespace>
<targetPackage>a.b.c</targetPackage>
</mapping>
</mappings>
<testCases>false</testCases>
<serverSide>false</serverSide>
<subPackageByFileName>true</subPackageByFileName>
</configuration>
<executions>
<execution>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
Now in above setting we just have namespaces mapped to package. I am just not able to get how this setting is able to track where does wsdl reside in order generate stubs?
Maven documentation is not very clear on this. Any ideas on this?
EDIT:
I did some testing on this:
I removed all the mappings of namespaces and packages but still wsdl gets picked up.
Even if i change the wsdl name, it still gets picked up.
This is very surprising to me, it seems axis plugin knows about wsdl location. but how i dont knw.
So finally i solved the mystery.
I ran maven build in debug mode : mvn -X clean insatll
I noticed that maven-axistools-plugin checks the default directory as ${basedir}/src/main/wsdl to search for wsdl and hence it was always able to locate my wsdls.
Most of our team consists of java developers and therefore the whole build / deployment / dependency management system is built on top of maven. We use CI so every build process runs unit test (w. karma and phantomJS for the frontend, and jasmine-node for the backend). I've managed to configure a karma maven plugin for this purpose.
This does not solve the issue of downloading node.js dependencies from package.json on build. I need to deploy my node.js / express app in existing environment, so the perfect scenario would be:
pull from the repo (done automatically with maven build)
npm install (that is - downloading dependencies from node package registry)
running tests
I was trying to find a nodejs package for maven, but to be honest - as a node.js developer I do not feel very confident when it comes to choosing the right tools, since I'm not able to distinguish a bad maven plugin from a decent one.
Maybe using a shell plugin and invoking npm install from the terminal is a better choice?
What's your opinion?
You've got two choices:
https://github.com/eirslett/frontend-maven-plugin to let maven download your npm modules from your package.json and let it automagically install node and npm all along
https://github.com/mulesoft/npm-maven-plugin to let maven download your npm packages that you have specified in the pom.xml (link dead as of April 2020, seems to be discontinued)
As a hacky solution, though still feasible you could as you've mentioned yourself, use something like maven-antrun-plugin to actually execute npm with maven.
All approaches have their pros and cons, but frontend-maven-plugin seems to be the most often used approach - but it assumes that your ci server can download from the internet arbitrary packages, whereas the "hacky" solution should also work, when your ci server has no connection to the internet at all (besides proxying the central maven repo)
I think you can find the answer in Grunt and the many available plugins.
I'm actually working on a web project where the client-side is made with AngularJS. Nevertheless, I think the deployement process may partially answer to your question :
In your pom.xml, you can do something like that:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>exec-gen-sources</id>
<phase>generate-sources</phase>
<configuration>
<target name="Build Web">
<exec executable="cmd" dir="${project.basedir}"
failonerror="true" osfamily="windows">
<arg line="/c npm install" />
</exec>
<exec executable="cmd" dir="${project.basedir}"
failonerror="true" osfamily="windows">
<arg line="/c bower install --no-color" />
</exec>
<exec executable="cmd" dir="${project.basedir}"
failonerror="true" osfamily="windows">
<arg line="/c grunt release --no-color --force" />
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
First part is the npm install task: downloading of dependencies from node package.
Second part is the bower install task: downoading of other dependencies with bower (in my case, AngularJS, but you might not need this part)
Third part is the Grunt Release part: launching a Grunt task that includes Karma unit testing.
You can find documentation about Grunt here. There are many available plugins like Karma unit testing.
I hope this helped you.
I made npm process work for my AngularJS 2 + Spring Boot application by exec-maven-plugin. I don't use bower and grunt, but think you can make it work by exec-maven-plugin too, after look at the antrun example above from Pear.
Below is my pom.xml example for exec-maven-plugin. My app has package.json and all the AngularJS .ts files are under src/main/resources, so run npm from the path. I run npm install for dependencies and npm run tsc for .ts conversion to .js
pom.xml
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>exec-npm-install</id>
<phase>generate-sources</phase>
<configuration>
<workingDirectory>${project.basedir}/src/main/resources</workingDirectory>
<executable>npm</executable>
<arguments>
<argument>install</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
<execution>
<id>exec-npm-run-tsc</id>
<phase>generate-sources</phase>
<configuration>
<workingDirectory>${project.basedir}/src/main/resources</workingDirectory>
<executable>npm</executable>
<arguments>
<argument>run</argument>
<argument>tsc</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
One little hack on this is running maven build on eclipse with Windows or Mac. It perfectly fine on eclipse with linux or even also fine on Windows command window though. When run build on eclipse with Windows, it fail to understand npm and complain about not find the file. Weird thing is npm is working fine on Windows command window. So solving the hack I create npm.bat file under system path. In my case nodejs and npm are installed under C:\Program File\nodejs. After putting this batch file. everything works fine.
npm.bat
#echo off
set arg1=%1
set arg2=%2
C:\Progra~1\nodejs\npm.cmd %arg1% %arg2%
For Mac, I got same issue on eclipse. The thing is nodejs and npm are installed under /usr/local/bin. So to solve the issue, I make symbolic link /usr/local/bin/node and /usr/local/bin/npm to under /user/bin. However /usr/bin is protected in security policy, I done that after booting from recovery disk
Since 2015, there is an alternative to the frontend-maven-plugin mentioned in
Christian Ulbrich's excellent answer:
https://github.com/aseovic/npm-maven-plugin
Usage
Basically, all you have to do to use it is to put it into your POM as usual (and use "extensions:true"):
<build>
<plugins>
<plugin>
<groupId>com.seovic.maven.plugins</groupId>
<artifactId>npm-maven-plugin</artifactId>
<version>1.0.4</version>
<extensions>true</extensions>
</plugin>
[...]
</plugins>
</build>
The plugin will then automatically bind to the Maven lifecycle. Then, you can put a script into your package.json, such as:
"scripts":
{
"package": "npm pack",
[...]
}
and the npm script "package" will run automatically as part of the Maven build lifecycle phase "package".
Compared to frontend-maven-plugin
Just like frontend-maven-plugin, it will run npm scripts inside a maven project. There are two important differences:
frontend-maven-plugin will (and must) download and install npm itself. npm-maven-plugin uses (and requires) an installed version of npm.
frontend-maven-plugin requires you to describe every npm invocation in the POM (as an "execution" section). In contrast, npm-maven-plugin simply extends the Maven build lifecycle to automatically execute an npm script with the same name for each lifecycle phase (clean, install etc.). That means there is no npm-specific configuration in the POM - it's all taken from package.json.
Personally, I prefer the npm-maven-plugin's approach because it requires less configuration in the POM - POMs have a tendency to get bloated, and everything to counter that helps. Also, putting the npm invocations into package.json feels more natural and allows reusing them when invoking npm directly.
Admittedly, even with the frontend-maven-plugin you can [and probably should] define all npm invocations as scripts in package.json, and invoke these scripts from the POM, but there is still the temptation to put them directly into the POM.
version is glassfish v3
I want to trying maven-glassfish-plugin but I don't know how to create a new domain.
You can use the create-domain command. Either pass parameters on the command line or follow the interactive steps:
$ asadmin create-domain
But the Maven GlassFish Plugin (once properly configured) can also create a domain with the following goal:
glassfish:create-domain Create a new Glassfish domain. (Creating an existing domain will cause it to be deleted and recreated.)
Here is a configuration sample (inspired by the Fairly Complete Configuration Example):
<plugin>
<groupId>org.glassfish.maven.plugin</groupId>
<artifactId>maven-glassfish-plugin</artifactId>
<version>2.2-SNAPSHOT</version>
<configuration>
<glassfishDirectory>${glassfish.home}</glassfishDirectory>
<user>${domain.username}</user>
<adminPassword>${domain.password}</adminPassword>
<!-- <passwordFile>path/to/asadmin/passfile</passwordFile> -->
<autoCreate>true</autoCreate>
<debug>true</debug>
<echo>true</echo>
<skip>${test.int.skip}</skip>
<domain>
<name>${project.artifactId}</name>
<httpPort>8080</httpPort>
<adminPort>4848</adminPort>
</domain>
<components>
<component>
<name>${project.artifactId}</name>
<artifact>${project.build.directory}/${project.build.finalName}.war</artifact>
</component>
</components>
</configuration>
</plugin>