Debugging and troubleshooting Apache Karaf 3 - json

So I've OSGI-ified a war file. It still works in Tomcat. I have all the requisite fields in the manifest and the libraries are all embedded for now. I'll externalize them later. There are two which are not OSGI enabled. The war file has log4j2 embedded BTW. It will be removed later.
The war file in question is 3 simple Jersey based REST/JSON services.
It starts and goes to Active state but I can't hit it with SoapUI where I expect to find it. The logs show it starting but that is all they show.
How can I squeeze more info out of Karaf so that I can properly figure out what is going on?
Is there something special I have to do in the Activator to get it to fire up?
Note: This is a simple REST / JSON service that wraps WURFL. By license, it's Open Source but it hasn't been released yet.
karaf#root()> bundle:headers MobileWURFL
MobileWURFL Maven Webapp (104)
-------------------------------
Manifest-Version = 1.0
Bnd-LastModified = 1395276484402
Archiver-Version = Plexus Archiver
Tool = Bnd-2.1.0.20130426-122213
Embed-Directory = WEB-INF/lib
Embedded-Artifacts = WEB-INF/lib/org.osgi.core-4.3.0.jar;g="org.osgi";a="org.osgi.core";v="4.3.0",WEB-INF/lib/org.osgi.compendium-1.4.0.jar;g="org.apache.felix";a="org.osgi.compend
ium";v="1.4.0",WEB-INF/lib/org.osgi.core-1.4.0.jar;g="org.apache.felix";a="org.osgi.core";v="1.4.0",WEB-INF/lib/javax.servlet-1.0.0.jar;g="org.apache.felix";a="javax.servlet";v="1.
0.0",WEB-INF/lib/org.osgi.foundation-1.2.0.jar;g="org.apache.felix";a="org.osgi.foundation";v="1.2.0",WEB-INF/lib/servlet-api-2.5.jar;g="javax.servlet";a="servlet-api";v="2.5",WEB-
INF/lib/log4j-api-2.0-rc1.jar;g="org.apache.logging.log4j";a="log4j-api";v="2.0-rc1",WEB-INF/lib/log4j-core-2.0-rc1.jar;g="org.apache.logging.log4j";a="log4j-core";v="2.0-rc1",WEB-
INF/lib/disruptor-3.0.1.jar;g="com.lmax";a="disruptor";v="3.0.1",WEB-INF/lib/commons-lang-2.6.jar;g="commons-lang";a="commons-lang";v="2.6",WEB-INF/lib/log4j-slf4j-impl-2.0-rc1.jar
;g="org.apache.logging.log4j";a="log4j-slf4j-impl";v="2.0-rc1",WEB-INF/lib/slf4j-api-1.7.5.jar;g="org.slf4j";a="slf4j-api";v="1.7.5",WEB-INF/lib/commons-collections-3.2.1.jar;g="co
mmons-collections";a="commons-collections";v="3.2.1",WEB-INF/lib/wurfl-1.5.1.jar;g="net.sourceforge.wurfl";a="wurfl";v="1.5.1",WEB-INF/lib/json-20140107.jar;g="org.json";a="json";v
="20140107",WEB-INF/lib/jersey-server-1.8.jar;g="com.sun.jersey";a="jersey-server";v="1.8",WEB-INF/lib/asm-3.1.jar;g="asm";a="asm";v="3.1",WEB-INF/lib/jersey-core-1.8.jar;g="com.su
n.jersey";a="jersey-core";v="1.8"
Built-By = Coder_Guy
Embed-Dependency = *;scope=compile|runtime
Embed-Transitive = true
Webapp-Context = MobileWURFL
Web-ContextPath = MobileWURFL
Build-Jdk = 1.7.0_51
Created-By = Apache Maven Bundle Plugin
Bundle-Name = MobileWURFL Maven Webapp
Bundle-SymbolicName = MobileWURFL
Bundle-Version = 0.0.1.SNAPSHOT
Bundle-ManifestVersion = 2
Bundle-ClassPath = .,WEB-INF/classes,WEB-INF/lib/org.osgi.core-4.3.0.jar,WEB-INF/lib/org.osgi.compendium-1.4.0.jar,WEB-INF/lib/org.osgi.core-1.4.0.jar,WEB-INF/lib/javax.servlet-1.0
.0.jar,WEB-INF/lib/org.osgi.foundation-1.2.0.jar,WEB-INF/lib/servlet-api-2.5.jar,WEB-INF/lib/log4j-api-2.0-rc1.jar,WEB-INF/lib/log4j-core-2.0-rc1.jar,WEB-INF/lib/disruptor-3.0.1.ja
r,WEB-INF/lib/commons-lang-2.6.jar,WEB-INF/lib/log4j-slf4j-impl-2.0-rc1.jar,WEB-INF/lib/slf4j-api-1.7.5.jar,WEB-INF/lib/commons-collections-3.2.1.jar,WEB-INF/lib/wurfl-1.5.1.jar,WE
B-INF/lib/json-20140107.jar,WEB-INF/lib/jersey-server-1.8.jar,WEB-INF/lib/asm-3.1.jar,WEB-INF/lib/jersey-core-1.8.jar

As you are using a OSGi-fied war the war-extender of Pax Web will kick in. Therefore no activator needed. For debugging just start the karaf container with karaf debug, attach your debuger to port 8787.
Depending on your embedded jars there might be an issue with those, for example a servlet.jar or similar will result in errors with deployment. Also possible the log4j2.jar could cause an issue.
What's the result of bundle:header for this war?
With the command
web:list
you also receive the info of the state of the web bundle.
UPDATE:
It is right there in your Bundle-ClassPath. The servlet jar is not allowed to be in a WAR, per spec by the way. In OSGi it collides with the packages provided by Pax-Web. In a Tomcat, the servlet.jar is already loaded by the container therefore it does work, as First-Come-First-Serve is used by a classloader. With OSGi the first Servlet class is found inside the War and therefore the resolver doesn't use the one provided by Pax Web. It is essential that you remove that jar.
And I think adding those osgi jars doesn't help any either, this will most likely collide with the bundles provided by the container.
I strongly suggest using the maven-bundle-plugin to generate this war, so the imports are properly created. Or just neglect all OSGi meta information and deploy a standard WAR. If you use the following type URL:
webbundle:mvn:groupID/artifactID/version/war?Web-ContextPath=Mobile-WURFL
It will generate a proper OSGi Manifest for your war.

Related

Quartz 2.6.2 and .NET Core? - Error "Could Not Initialize DataSource"

I'm using an older version of Quartz.NET (v2.6.2) with .NET Core (or possibly .NET5). I'm getting an error when attempting to use the StdSchedulerFactory.GetScheduler. All my configuration settings are within my appsettings.json where I populate a NameValueCollection with these values and inject them into my classes with DI.
["quartz.scheduler.instanceId"] = "instance_one",
["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz",
["quartz.threadPool.threadCount"] = "5",
["quartz.jobStore.misfireThreshold"] = "60000",
["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz",
["quartz.jobStore.useProperties"] = "false",
["quartz.jobStore.dataSource"] = "default",
["quartz.jobStore.tablePrefix"] = "QRTZ_",
["quartz.dataSource.default.provider"] = "SqlServer-20",
["quartz.dataSource.default.connectionString"] = quartzConn
I am using the StdSchedulerFactory like this, where Settings.Properties is that NameValueCollection which contains all the config settings:
var factory = new StdSchedulerFactory(Settings.Properties);
var scheduler = factory.GetScheduler();
On the GetScheduler method, the error, "Could Not Initialize Datasource: default" is thrown.
The crazy thing is this code works fine in a Framework 4.x project that uses a regular web.config to supply the configuration settings. Also, when I change to use Quartz 3.X with my code above, with configurations in the appsettings.json works fine. Seems that me mixing and matching both versions is causing an issue where Quartz doesn't know how to retrieve some value?
Is there a way to manually build my scheduler and not use the factory?
Thanks!
I've had to go back to Framework 4 and Quartz 2.6 to get them to play nicely together. I can only get Quartz 3.x to work with .NET Core/5. Stepping through the source code with dotPeek, Quartz 2.6 is using ConfigurationManager to pull web.config details that don't exist in Core/5. At this point I don't remember if I tried to add my own web.config file to this project or not, but I've since moved on.

Can the ConfigurationAPI in Liferay DXP be used for Plugin sdk portlet?

I have followed given 2 tutorials to use COnfigurationAPI in a Liferay dxp plugins SDK portlet built using Ant/Ivy.
COnfiguration API 1
COnfiguration API 2.
Below is the configuration class used:
package com.preferences.interfaces;
import com.liferay.portal.configuration.metatype.annotations.ExtendedObjectClassDefinition;
import aQute.bnd.annotation.metatype.Meta;
#ExtendedObjectClassDefinition(
category = "preferences",
scope = ExtendedObjectClassDefinition.Scope.GROUP
)
#Meta.OCD(
id = "com.preferences.interfaces.UnsupportedBrowserGroupServiceConfiguration",
name = "UnsupportedBrowser.group.service.configuration.name"
)
public interface UnsupportedBrowserGroupServiceConfiguration {
#Meta.AD(deflt = "", required = false)
public String displayStyle();
#Meta.AD(deflt = "0", required = false)
public long displayStyleGroupId(long defaultDisplayStyleGroupId);
}
Post following the steps,I am getting the below error:
ERROR [CM Configuration Updater (ManagedService Update: pid=[com.preferences.interfaces.UnsupportedBrowserGroupServiceConfiguration])][org_apache_felix_configadmin:97] [org.osgi.service.cm.ManagedService, id=7082, bundle=297//com.liferay.portal.configuration.settings-2.0.15.jar?lpkgPath=C:\dev\Liferay\osgi\marketplace\Liferay Foundation.lpkg]: Unexpected problem updating configuration com.preferences.interfaces.UnsupportedBrowserGroupServiceConfiguration {org.osgi.service.cm.ConfigurationAdmin}={service.vendor=Apache Software Foundation, service.pid=org.apache.felix.cm.ConfigurationAdmin, service.description=Configuration Admin Service Specification 1.2 Implementation, service.id=56, service.bundleid=643, service.scope=bundle}
Caused by: java.lang.IllegalArgumentException: wrong number of arguments
So,does this process need a osgi module as mandatory or can we do it using plusings sdk portlet built using ant as well?
Without disecting the error message Caused by: java.lang.IllegalArgumentException: wrong number of arguments:
The way you build your plugin (Ant, Maven, Gradle, manually) doesn't make a difference, as long as you build a plugin that will be understood by the runtime. aQute.bnd.annotation.metatype.Meta points firmly into the OSGi world, and makes it almost certain that you'll need an OSGi module. You can build this with Ant, of course. Even in Ant you can embed tools like bnd, or you can write the proper Manifest.mf to include in your module manually (just kidding - you don't want to do it manually, but it would work).
Recommendation: Instead of moving everything over: Try to reproduce this with a minimal example in gradle or better Liferay Workspace (which is gradle based), just to get all the automatic wiring in. Check if it makes a difference and compare the generated output from your Ant build process with the workspace output. Pay specific attention to the Manifest.
In order to build the proper Manifest, you want to use bnd - if the Manifest turns out to be your issue: Find a way to embrace bnd - if that's by saying goodby to Ant, or by tweaking your build script remains your decision.

What is the activator command to generate application secret?

I'm using Play Framework 2.3.6. Since Play 2.3.x play commands are replaced with activator commands. Play's documentation for 2.3.x as well as latest 2.4.x mentions commands play-generate-secret and play-update-secret but I am not able to find corresponding activator commands.
We may not choose to use these secrets for production environment but would like play to generate secrets for integration and pre-prod environments - which we can change frequently.
Has anyone done this before? What are the proper activator commands?
Both
activator play-generate-secret
and
activator play-update-secret
work well for the Activator.
You can find their definition here in the sources. And as you can see they are part of Play and not the Activator.
val generateSecret = TaskKey[String]("play-generate-secret", "Generate a new application secret", KeyRanks.BTask)
val updateSecret = TaskKey[File]("play-update-secret", "Update the application conf to generate an application secret", KeyRanks.BTask)
As the comment from #john mentions, this is
activator playGenerateSecret
from Play 2.4 onwards.

Logback config, puppet and application versions

I am busy testing a new approach to managing a java application that uses logback on a puppet-managed host, and was wondering if anyone had some advice on the best approach for this. I am stuck with a catch 22 situation.
The java application is deployed to a host by an automated system (CI). The deployment writes an application version number to a file (e.g. /etc/app.version may contain "0001")
The logback config file (logback.xml) is managed by puppet.
I am trying to configure the application to include it's version number in the logging layout (e.g. <pattern>VERSION: %version%</pattern> . However, I am not sure on the approach, as there isn't an "include" function for the logback config file (to include a file with the version number into the logback config). At the same time, I don't see a way to get puppet to do a client-side template build, using the host-side file (I've tried using a template approach, but the template is compiled on the puppet server side).
Any idea's on how to get this working?
I would write a custom fact. Facts are executed on the client.
Eg:
logback/manifests/init.pp
file { '/etc/logback.xml':
content => template('logback/logback.xml.erb')
}
logback/templates/logback.xml.erb
...
<pattern>VERSION: <%= scope.lookupvar('::my_app_version') %></pattern>
...
logback/lib/facter/my_app_version.rb
Facter.add('my_app_version') do
setcode do
begin
File.read('/etc/app.version')
rescue
nil
end
end
end
Hope that helps. I think in Puppet < 3.0 you will have to set "pluginsync = true" in puppet.conf to get this to work.

Quartz.net Setup Throwing Error: "onfiguration parser encountered <job>"

I have a Asp.net C# MVC 3 application implementing the Sharp Architecture. I have been trying to get Quartz.net to setup and work nicely with Castle Windsor for a few days without any luck. Based on what I know, I have setup everything correctly, but continue to have issues.
In my Global.cs file, creating my Container and trying to register quartz jobs:
var container = new WindsorContainer(new XmlInterpreter("quartz_jobs.xml"));
container.AddFacility("quartznet", new QuartzFacility());
In my quartz_jobs.xml file I have the following contents:
<?xml version="1.0" encoding="utf-8" ?>
<quartz xmlns="http://quartznet.sourceforge.net/JobSchedulingData"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="1.0"
overwrite-existing-jobs="true">
<job>
<job-detail>
<name>DeleteLoansWithoutClientsJob</name>
<job-type>EasyOptions.Web.Mvc.Code.Jobs.DeleteLoansWithoutClientsJob, EasyOptions.Web.Mvc</job-type>
<durable>true</durable>
</job-detail>
<trigger>
<cron>
<name>DeleteLoansWithoutClientsJobTrigger</name>
<group>MyJobs</group>
<description>A description</description>
<job-name>DeleteLoansWithoutClientsJob</job-name>
<job-group>MyJobs</job-group>
<cron-expression>0 0/1 * * * ?</cron-expression>
</cron>
</trigger>
</job>
Problem is, you're pointing Windsor to the Quartz.NET config file.
There are two separate configurations: Windsor's and Quartz.NET's. Windsor is usually configured with code nowadays (i.e. fluent config), though it still supports XML configuration. However the Quartz.NET facility doesn't currently support code config, you have to use Windsor's XML config (at least for this, other components/facilities may still be configured via code). Then there's Quartz.NET, usually configured via an external quartz_jobs.xml file.
I recommend using the Quartz.NET facility sample app as reference. In particular, here's the sample Windsor config and the sample Quartz.NET config.
EDIT: if Quartz.NET says it can't find quartz_jobs.xml in a web application you need to include the web root in the configuration path: "~/quartz_jobs.xml" (instead of plain "quartz_jobs.xml")
I've written a blog post on how to integrate Quartz.NET with an IoC container. My example code uses Castle Windsor.
The blog post can be found here: http://thecodesaysitall.blogspot.com/2012/02/integrate-quartznet-with-your-favourite.html