Embedding Glassfish v2.1.1 - glassfish

I have an application running on Glassfish v2.1.1 on a server and I'm looking to generate a portable (read: no-installation-required) version of it. I don't want to move to another container (Glassfish 3, Tomcat, etc.) because it will introduce new problems and bugs. I prefer to stick to the same container.
I've started taking apart the Glassfish distribution and there are some references there to paths which hint that installation is required. Has anyone been successful at generating a portable Glassfish based on v2.1.1?

Basic examples of embedding GlassFish and deploying applications to embedded GlassFish:
These examples are can be run with either of the following jars in your CLASSPATH:
Full profile uber jar : http://download.java.net/maven/glassfish/org/glassfish/extras/glassfish-embedded-all/3.1/glassfish-embedded-all-3.1.jar
Web profile uber jar: http://download.java.net/maven/glassfish/org/glassfish/extras/glassfish-embedded-web/3.1/glassfish-embedded-web-3.1.jar
Installed GlassFish's shell jar : $GF_INSTALLATION/lib/embedded/glassfish-embedded-static-shell.jar
Once you have ANY ONE of the above jar file with you, GlassFish can be embedded in your application by simply doing:
import org.glassfish.embeddable.*;
/** Create and start GlassFish */
GlassFish glassfish = GlassFishRuntime.bootstrap().newGlassFish();
glassfish.start();
Let us say that you would like 8080 web container port to be started while embedding GlassFish, then you have to do this:
import org.glassfish.embeddable.*;
/** Create and start GlassFish which listens at 8080 http port */
GlassFishProperties gfProps = new GlassFishProperties();
gfProps.setPort("http-listener", 8080); // refer JavaDocs for the details of this API.
GlassFish glassfish = GlassFishRuntime.bootstrap().newGlassFish(gfProps);
glassfish.start();
Once you have the GlassFish embedded and is running, you may like to deploy a pre-built Java EE archive using the code below:
import org.glassfish.embeddable.*;
// Obtain the deployer from the glassfish which is embedded via the piece of code above.
Deployer deployer = glassfish.getDeployer();
// syntax of deployment params are same as how they are passed to 'asadmin deploy' command.
deployer.deploy(new File("simple.war"), "--contextroot=test", "--name=test", "--force=true");
// if you have no deployment params to pass, then simply do this:
deployer.deploy(new File("simple.war"));
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())
Similarly, the scattered enterprise application (EAR type) can be deployed like this:
import org.glassfish.embeddable.*;
import org.glassfish.embeddable.archive.*;
Deployer deployer = glassfish.getDeployer();
// Create a scattered web application.
ScatteredArchive webmodule = new ScatteredArchive("testweb", ScatteredArchive.Type.WAR);
// target/classes directory contains my complied servlets
webmodule.addClassPath(new File("target", "classes"));
// resources/sun-web.xml is my WEB-INF/sun-web.xml
webmodule.addMetadata(new File("resources", "sun-web.xml"));
// Create a scattered enterprise archive.
ScatteredEnterpriseArchive archive = new ScatteredEnterpriseArchive("testapp");
// src/application.xml is my META-INF/application.xml
archive.addMetadata(new File("src", "application.xml"));
// Add scattered web module to the scattered enterprise archive.
// src/application.xml references Web module as "scattered.war". Hence specify the name while adding the archive.
archive.addArchive(webmodule.toURI(), "scattered.war");
// lib/mylibrary.jar is a library JAR file.
archive.addArchive(new File("lib", "mylibrary.jar"));
// target/ejbclasses contain my compiled EJB module.
// src/application.xml references EJB module as "ejb.jar". Hence specify the name while adding the archive.
archive.addArchive(new File("target", "ejbclasses"), "ejb.jar");
deployer.deploy(archive.toURI())
Finally, towards the end of your application, you would like to stop/dispose your embedded GlassFish:
import org.glassfish.embeddable.*;
/** Stop GlassFish */
glassfish.stop(); // you can start it again.
/** Dispose GlassFish */
glassfish.dispose(); // you can not start it again. But you can embed a fresh glassfish with GlassFishRuntime.bootstrap().newGlassFish()

Related

getClassPath() method in the WebLogic context class loader does not consider package preferences in weblogic.xml

A related problem: Get the class path from the context class loader (of WebLogic for instance)
This is already solved in How to set up the context class loader's classpath for runtime compilation?.
Current problem: Get the same (proper) class path used to run a web app
Reflectively calling the "getClassPath()" method works but it returns a dirty classpath containing unanted modules from $ORACLE_HOME/oracle_common/modules directory.
Problematic scenario:
Deploy a web app "Parent" in WebLogic // <- works
Get the context class path (it's a String object) by reflexively calling "getClassPath()" // <- works
Fork a process out of the main "Parent" process and run it using the context class path // <- fails
04:36:45,238 [Thread-41] ERROR ChildProcess - Exception in thread "main" java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.ObjectMapp
er.configOverride(Ljava/lang/Class;)Lcom/fasterxml/jackson/databind/cfg/MutableConfigOverride;
Explanation
While the context class path contains the necessary dependencies for the child process to run, they are overshadowed by WebLogic's own dependencies. The result is runtime failures such as the one shown above.
Workaround
a) Use a new version of WebLogic server that hopefully would use newer versions of the artifacts needed by the child process // risky endeavour
b) Manually process the context class path and remove any artifact that would shadow their more-recent counterparts
Solution b) looks more practical, but I don't like it for meany reasons:
The reflexive call to "getClassPath" returns a String, and looking for artifact's names in Strings feels frail and weak
I wouldn't know what shadows what. WebLogic prepends its weird artifacts at the start of the string before listing the web app's own dependencies.
Only weblogic.xml has info on the web app's package preferences. I wish I could mimic how WebLogic processes this file to run the web app (Parent) and use that to properly run the child process
It seems to me that forking a process out from a web app running in WebLogic does not enjoy the same package preferences expressed in "weblogic.xml" that the web app (Parent) enjoyed when it was deployed and started running.
Other than the above suggestions, I am welcoming of any stronger solutions

Playframework 2.5 and Intellij IDEA

I am using IDEA for my Playframework development. However, I don't seem to be able to run/debug my application anymore I was able to do two months ago. I haven't done any active development on this project, and there have been updates to IDEA.
When I now debug my application it doesn't not load the 'dev' configuration file.
This is specified as -Dconfig.resource=application.dev.conf under JVM options on the Run/Debug configurations.
This used to work fine, but it now loads the application.conf which contains the default db parameters to connect to a MySQL server and not the mem server. I don't think I have changed anything. A ny pointers what can be wrong?
I am still on sbt-plugin 2.5.16.
[Edit]
Loading config from properties {jline.esc.timeout=0, config.resource=application.dev.conf, java.runtime.name=Java(TM) SE Runtime Environment, sun.boot.library.path=/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib, java.vm.version=25.25-b02, user.country.format=IE, gopherProxySet=false, java.vm.vendor=Oracle Corporation, java.vendor.url=http://java.oracle.com/, path.separator=:, java.vm.name=Java HotSpot(TM) 64-Bit Server VM, file.encoding.pkg=sun.io, user.country=GB, sun.java.launcher=SUN_STANDARD, sun.os.patch.level=unknown, java.vm.specification.name=Java Virtual Machine Specification, user.dir=/Users/xxx/Documents/Java/Y2kBooking, java.runtime.version=1.8.0_25-b17, java.awt.graphicsenv=sun.awt.CGraphicsEnvironment, java.endorsed.dirs=/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/endorsed, os.arch=x86_64, java.io.tmpdir=/var/folders/6g/mllv8zcn73v3p9mgt8f78jd80000gn/T/, line.separator=
, java.vm.specification.vendor=Oracle Corporation, os.name=Mac OS X, sun.jnu.encoding=UTF-8, java.library.path=/Users/xxx/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:., jboss.modules.system.pkgs=com.intellij.rt, java.specification.name=Java Platform API Specification, java.class.version=52.0, sun.management.compiler=HotSpot 64-Bit Tiered Compilers, os.version=10.13.2, http.nonProxyHosts=local|*.local|169.254/16|*.169.254/16, user.home=/Users/xxx, user.timezone=Europe/Dublin, java.awt.printerjob=sun.lwawt.macosx.CPrinterJob, java.specification.version=1.8, file.encoding=UTF-8, user.name=xxx, java.class.path=/Users/xxx/Library/Application Support/IntelliJIdea2017.3/Scala/launcher/sbt-launch.jar:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar:/Users/xxx/Library/Caches/IntelliJIdea2017.3/captureAgent/debugger-agent.jar, jline.shutdownhook=false, java.vm.specification.version=1.8, sun.arch.data.model=64, java.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre, sun.java.command=xsbt.boot.Boot run, java.specification.vendor=Oracle Corporation, user.language=en, awt.toolkit=sun.lwawt.macosx.LWCToolkit, config.trace=loads, java.vm.info=mixed mode, java.version=1.8.0_25, java.ext.dirs=/Users/xxx/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java, sun.boot.class.path=/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre/classes:/Users/xxx/Library/Caches/IntelliJIdea2017.3/captureAgent/debugger-agent-storage.jar, java.vendor=Oracle Corporation, file.separator=/, java.vendor.url.bug=http://bugreport.sun.com/bugreport/, sun.cpu.endian=little, sun.io.unicode.encoding=UnicodeBig, socksNonProxyHosts=local|*.local|169.254/16|*.169.254/16, ftp.nonProxyHosts=local|*.local|169.254/16|*.169.254/16, sun.cpu.isalist=}
Loading config from class loader sbt.PluginManagement$PluginClassLoader#4cc89246 but there were no resources called application.dev.conf
exception loading application.dev.conf: java.io.IOException: resource not found on classpath: application.dev.conf
Loading config from a String akka {
log-dead-letters = 0
log-dead-letters-during-shutdown = off
}
Loading config from resource 'reference.conf' URL jar:file:/Users/xxx/.ivy2/cache/scala_2.10/sbt_0.13/com.typesafe.sbt/sbt-js-engine/jars/sbt-js-engine-1.1.3.jar!/reference.conf from class loader sbt.PluginManagement$PluginClassLoader#4cc89246
Loading config from a URL: jar:file:/Users/xxx/.ivy2/cache/scala_2.10/sbt_0.13/com.typesafe.sbt/sbt-js-engine/jars/sbt-js-engine-1.1.3.jar!/reference.conf
Try debugging the configuration loading with -Dconfig.trace=loads as described here.
The -Dconfig.resource option loads a file from the classpath so make sure that file is in your IntelliJ classpath. I assume you put the file in the usual conf directory? You may need to check the IntelliJ Project Structure settings to make sure it includes that directory as a Resource Folder.
Finally, you may wish to check that the application works correctly when run using sbt run or sbt start.

IntelliJ run vs running a jar, with a Springboot Kotlin, Multi module Gradle project with Social Oauth2

TL;DR: Why does everything run fine when started via IntelliJ, and why is it broken when call java -jar app.jar. And how do I fix this?
Alright, I have some issues with a backend I am trying to dockerize. I have an application created with Spring Boot (1.4.2.RELEASE) following the Spring Oauth (2.0.12.RELEASE) guide on their page. I follow the Gradle version, since I prefer Gradle over Maven. Also I am using Kotlin instead of Java. Everything is fine, I start via IntelliJ my backend with static front end, I can login via Facebook (and Google and Github), I receive a nice Principal witch holds al the information I need, and I can modify Spring Security to authorize and permit endpoints. So far so good.
Now for the bad part, when I run either ./gradlew clean build app:bootrun or ./gradlew clean build app:jar and run the jar via java -jar (like I will do in my Docker container), my backend comes up. My static front end pops up. Now I want to login via Facebook, I end up on the Facebook login page, I enter my credentials, and... nothing!
I end up back on my homepage, not logged in, no log messages that mean anything to me, just silence. The last thing I see in the log is:Getting user info from: https://graph.facebook.com/me
This Url will give me in my browser:
{
"error": {
"message": "An active access token must be used to query information about the current user.",
"type": "OAuthException",
"code": 2500,
"fbtrace_id": "GV/58H5f4fJ"
}
}
When going to this URL via an IntelliJ start, it will give me credential details. Obviously something is going wrong, but I have no clue what. Especially since a run from IntelliJ works fine. There is some difference between how the jar is started, and how IntelliJ's run config works, but I have no clue where to search for what. I could post trace logging, or all my Gradle files, but perhaps thats too much info to put in 1 question. I will defenitly update this question if someone needs some more details :)
The structure outline of this project is as follows:
root:
- api: is going to be opensourced later, contains rest definitions and DTOs.
- core: contains the meat. Also here is included in the gradle file
spring-boot-starter, -web, -security, spring-security-oauth2, and some jackson stuff.
- rest: contains versioned rest service implementations.
- app: contains angular webjars amongst others, the front end, and
my `#SpringBootApplication`, `#EnableOAuth2Client`
and the impl of `WebSecurityConfigurerAdapter`.
Why does everything run fine when started via IntelliJ, and why is it broken using bootRun or the jar artefact. And how do I fix this?
I found it, the problem was not Multi module Graldle, Spring boot, or Oauth2 related. In fact it was due to a src set config of Gradle, where Java was supposed to be in a Java src set folder, and Kotlin in a Java src set folder:
sourceSets {
main.java.srcDirs += 'src/main/java'
main.kotlin.srcDirs += 'src/main/kotlin'
}
As Will Humphreys stated in his comment above, IntelliJ takes all source sets, and runs the app. However, when building the jar via Gradle, these source sets are stricter. I had a Java file in my Kotlin src set, which is no problem for IntelliJ. But the jar created by Gradle takes into account the source sets as defined in the build.gralde file, which are stricter.
I found my missing bean issue with the code below:
#Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
return args -> {
System.out.println("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
}
};
}
The Bean I missed was called AuthenticationController, which is a #RestController, and kinda crucial for my authentication code.

Jython does not resolve python imports from bundled Lib files/folders on Weblogic 10.3.5

I am new to Jython and Python, trying to build a prototype that makes use of Python code to be called from within Java. The code I am developing works in Jetty and in standalone mode (running java -jar from the command line), but not when deployed to weblogic.
How can I make weblogic(10.3.5) server/Jython recognize the Lib folder within jython-standalone-2.5.4-rc1.jar?
My Java code uses the JythonObjectFactory to invoke python modules as outlined in the Jython book:
http://www.jython.org/jythonbook/en/1.0/JythonAndJavaIntegration.html
The Python modules are using external libraries like csv, logging etc. that are not packaged with jython.jar, hence I am using jython-standalone jar.
The java code includes an interface that would define the class type of the first invoked py module from within java. The interface and the input and output (to python modules) type classes are in a package structure as com.abc.xpackage. and the py modules exist at the root of this package. A controller layer calls the objectfactory and in turn executes the python code thus:
JythonObjectFactory calFactory = new JythonObjectFactory(CalcType.class, "Calculate", "Calculate");
CalcType engine = (CalcType)calFactory.createObject();
output = engine.execute(input);
The entire code is bundled as a jar file which would become part of a web application deployed on weblogic. The code was compiled with maven (with jython dependencies included in the repository) and runs fine on the included Jetty runtime within eclipse.
When deployed on weblogic, however, I get a "ImportError: no module named csv" error.
To analyze what is happening, I tried printing the Jython system state path on weblogic and the standalone environment/Jetty. What I found is,
on Jetty, the system path consists of the following:
C:\.m2\repo\org\python\jython\jython-standalone-2.5.3-rc1.jar\Lib, ____classpath__, ____pyclasspath__
on Weblogic, printing the system path by default shows the following:
____classpath__, ____pyclasspath__
I tried forcing the inclusion of the missing path using the code as follows:
public JythonObjectFactory(PySystemState state, Class interfaceType, String moduleName, String className) {
String pathToAppend = new File(state.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getAbsolutePath()+"\\Lib";
state.path.insert(0, new PyString(pathToAppend));
state.path.append(new PyString(pathToAppend));
System.out.println("Jython sys path: "+state.path);
Please note, I prepended as well as appended the path in different trials. The sys path on weblogic now displays the following:
Jython sys path: ['C:\\wldomain\\wls135\\servers\\cgServer\\tmp\\app-1\\war\\WEB-INF\\lib\\jython-standalone-2.5.4-rc1.jar\\Lib', '__classpath__', '__pyclasspath__/', 'C:\\wldomain\\wls135\\servers\\cgServer\\tmp\\app-1\\war\\WEB-INF\\lib\\jython-standalone-2.5.4-rc1.jar\\Lib']
I am still getting ImportError despite this forcing of sys path. Please help why this works in a local environment, and not on weblogic, and if there is any configuration I am missing. Apologize for the rambling long post, I did not know how to explain the problem better. I will try and include any code/artifacts as needed.
Based on a comment(by Lassi) on the blog post below:
http://www.petervannes.nl/files/e1c3c56d15d25dcfd4adb5397a9ef71e-53.php
The jython issue was resolved after explicitly adding the Lib folder python.path to the weblogic startup script as a JAVA_OPTION.
In my case I added the exploded Lib folder to the domain server lib, but based on my test this works also from within the jython jar. Both the following JAVA_OPTIONS worked:
-Dpython.path=C:\wldomain\wls135\lib\Lib
-Dpython.path=C:\wldomain\wls135\lib\jython-standalone-2.5.4-rc1.jar\Lib
The programmatic way of sys.path.append worked for the local environment(jetty) but did not seem to work for weblogic.

Running Servlets in Apache Tomcat

I'm working through the Java Ranch Cattle Drive online tutorials and got up to the Servlets projects. I wanted to install and run Apache instead of Orion, because I wanted to learn a more mainstream HTTP server.
I got Apache up and running on my machine (this is a Windows XP/Cygwin environment, so I'm using the Apache package that comes with the latest version of cygwin, currently httpd version 1.3.33)
I'm to the point of directing a browser to http://localhost and the server is correctly fetching the welcome page (index.html) at C:\cygwin\var\www\htdocs.
I've installed Java EE and was able to compile the following Servlet:
import java.io.* ;
import javax.servlet.http.* ;
public class BeeServlet extends HttpServlet
{
public void doGet( HttpServletRequest request , HttpServletResponse response )
{
response.setContentType("text/html");
try
{
PrintWriter out = response.getWriter();
out.println( "a-buzz-buzz ..." );
out.close();
}
catch( Exception e )
{
System.out.println( "cannot get writer: " + e );
}
}
}
This compiles into a .class file without errors. My question is, where do I install this file in the server?
The file is called BeeServlet.class and the tutorial says to direct a browser to http://localhost/servlet/BeeServlet after installing the BeeServlet.class in the appropriate directory in the web server.
(EDIT: I've successfully installed Tomcat and have the basic welcome page showing, as explained in the steps below. I'm still not sure where to put the .class file though or how to access it):
Here's are the steps of installing Tomcat and running it through Cygwin:
Go to http://tomcat.apache.org/ and download the latest version of Tomcat (for the above system configuration, select the 32-bit/64-bit Windows Service Installer method, which will create a 9 MB installation at C:\Program Files\Apache Software Foundation\Tomcat 7.0).
Add this path to the Windows system environment variable 'Path'
Start a Cygwin bash shell
type 'tomcat7' (with Path set, it will find this .exe in the above path). This will start the tomcat server.
Start a browser and direct it to http://localhost:8080. This will bring up the Tomcat welcome screen (which is really Tomcat reading the file: C:\Program Files\Apache Software Foundation\Tomcat 7.0\webapps\ROOT\index.jsp).
Create new directories under C:\Program Files\Apache Software Foundation\Tomcat 7.0\webapps named examples\WEB-INF\classes.
Add a #WebServlet annotation to the source code file (this would be located after any imports): #WebServlet(urlPatterns={"/servlet/BeeServlet"}). Compile the BeeServlet.java file and place the .class file in C:\Program Files\Apache Software Foundation\Tomcat 7.0\webapps\examples\WEB-INF\classes\BeeServlet.class
Direct your browser to http://localhost:8080/examples/servlet/BeeServlet
You need to let the servletcontainer know that you've a servlet which it has to execute. Since you're already on Tomcat 7.0, a #WebServlet annotation should suffice.
#WebServlet(urlPatterns={"/servlet/BeeServlet"})
public class BeeServlet extends HttpServlet {
// ...
}
Or the old way (probably as the JavaRanch tutorial should have mentioned), by a declaration in web.xml.
<servlet>
<servlet-name>beeServlet</servlet-name>
<servlet-class>BeeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>beeServlet</servlet-name>
<url-pattern>/servlet/BeeServlet</url-pattern>
</servlet-mapping>
Please note that putting classes in a default package is a bad practice. You should be placing classes in a package if you want them to be visible to classes inside a package. The servletcontainer, written in pure Java, needs to be able to see them as well. Now, Tomcat has hacks for this, but this works in specific versions/configurations only. Always, always put servlet classes in a package.
See also:
Our servlets wiki page
Unrelated to the concrete problem:
I've installed Java EE
Please note that the Java EE download from Oracle.com contains basically the Glassfish application server along with some documentation. You don't need it when all you want is just running servlets on Tomcat.
See also:
Java SE or Java EE (standard or enterprise)?
Apache is a web server, not a servlet/JSP engine. Tomcat is a servlet/JSP engine; so is Jetty. You'll need to deploy your servlets/JSPs on Tomcat and tell Apache to forward requests to your servlets/JSPs to Tomcat.