Error while extracting zip file created from maven assembly plugin - zip

I'm using maven assembly plugin to create a zip packaging resources from another maven module in the same project.
Parent_project
|_module1
|_resources
|_templates
|_abc.xml
|_module2
|_resources
|_build-config.xml
Below is my build-config.xml file.
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>bundle</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${basedir}/../module1/src/main/resources/templates</directory>
<includes>
<include>*.xml</include>
</includes>
<outputDirectory>/testdir</outputDirectory>
</fileSet>
</fileSets>
</assembly>
I'm able to copy the resources to a sub-directory named testdir inside the zip file's root. (I can observe this by viewing the zip file without extracting it.) But if i try to extract the zip, it gives me the below error.
There was an error while extracting the sample.zip. "sample/testdir/abc.xml": Not a directory.
I'm using Ubuntu 18 with maven assembly plugin version -1.1.2
Can someone please point me the issue here?

I tried for a while and observed below. Extracting through UI option causes the error. If i were to use the unzip ./myzip.zip -d . command, the extraction success.
But i found a workaround for this as below.
Create an empty directory first.
<fileSet> <!-- Create empty directory -->
<outputDirectory>./templates</outputDirectory>
<excludes>
<exclude>**/*</exclude>
</excludes>
</fileSet>
Copy resources to the directory.
<fileSet>
<directory>${basedir}/test</directory>
<includes>
<include>*.xml</include>
</includes>
<outputDirectory>./templates</outputDirectory>
</fileSet>
This method fixes the issue while extracting the zip. Cheers!

Related

Package and install a xxx.desktop file with javapackager

I've packaged an application with Maven's JavaPackager plugin targetting Linux.
Everything is working fine except that I don't find how to package and install a "xxxx.desktop" file for my application.
Without this file, 1/ the icon on the launcher is ugly, 2/ the application cannot be found with a Search.
Here is my plugin's config:
<plugin>
<groupId>io.github.fvarrui</groupId>
<artifactId>javapackager</artifactId>
<version>1.6.7</version>
<configuration>
<mainClass>com.zparkingb.zploger.GUI.Zploger</mainClass>
<generateInstaller>false</generateInstaller>
<administratorRequired>false</administratorRequired>
</configuration>
<executions>
<execution>
<!-- With JRE -->
<id>bundling-for-platform-complete</id>
<phase>package</phase>
<goals>
<goal>package</goal>
</goals>
<configuration>
<platform>linux</platform>
<name>${project.bundle_finalname}${package.buildnamesuffix}</name>
<outputDirectory>${project.build.directory}/FULL</outputDirectory>
<createTarball>true</createTarball>
<createZipball>false</createZipball>
<bundleJre>true</bundleJre>
<customizedJre>false</customizedJre>
<!--From settings.xml-->
<jrePath>${package.jrePath}</jrePath>
<jdkPath>${package.jdkPath}</jdkPath>
<!--Special for Linux-->
<linuxConfig>
<pngFile>assets/linux/Zploger.png</pngFile>
<generateAppImage>true</generateAppImage>
<generateDeb>false</generateDeb>
<generateRpm>false</generateRpm>
<wrapJar>true</wrapJar>
<categories>
<category>Utility</category>
</categories>
</linuxConfig>
</configuration>
</execution>
</executions>
</plugin>
So I'd need to end up with file:
~/.local/share/applications/com-zparkingb-zploger-GUI-Zploger.desktop
with a similar content:
[Desktop Entry]
Encoding=UTF-8
Version=1.0
Type=Application
Terminal=false
Name=Zploger for Scores
Icon=/home/vboxuser/Desktop/ZplogerScores/Zploger.png
Or even having the icon placed somewhere in ~/.local/share/icons/xxx/xxx and having the ".desktop" file refering to it as Icon=Zploger
How could I achieve this ?
My solution is probably far from being ideal, but I am limited in that I am building a Linux solution from a Windows environment.
The solution is based on the following principle:
Have the application startup script checking for the presence of the icons and the .desktop file in ~/.local/share/applications/.
If it doesn't exist, copy these from the package.
So the solution must
Adapt the default startup script in order to do that extra check
Add in the packaging the desktop file and the icons.
In the end, the solution is comprised of the following 4 steps:
Add to the project folder the icons and the desktop file. I've put these in a bundledata/linux/assets folder. The folder name is free but cannot be assets\ because this one is reserved for JavaPackager and cannot one of the Maven resources folder because I want these files to packaged separately.
Provide an adapted startup.sh.vtl velocity template which goal is to add to the startup script instructions to copy the icons and a valid desktop file.
The icons are copied to ~/.local/share/icons/hicolor/.
And I provide "./16x16", "./24x24", ... "./1024x1024". And also "./scalable" with a SVG version of the application icon.
The desktop file is named my-main-class.desktop (in my case com-zparkingb-zploger-GUI-Zploger.desktop) and is copied into ~/.local/share/applications/
Have that script modifying the xxx.desktop to push the current script path.
Adapt the pom.xml.
In the io.github.fvarrui.javapackager plugin's config, add the following instruction:
<additionalResources>
<additionalResource>bundledata/linux/assets</additionalResource>
</additionalResources>

log4j.properties does not have effects on logging in activeJDBC

I am currently working on a simple web application using javalite webactive and activeJDBC. To start with javalite I simply used https://github.com/javalite/activeweb-simple/ and expanded from there.
One thing which I would like to change, now that I have already implemented a few controllers and models I want to customize the logger:
[qtp1442407170-13] INFO org.javalite.activeweb.RequestDispatcher - {"controller":"app.controllers.HomeController","duration_millis":685,"remote_ip":"0:0:0:0:0:0:0:1","method":"GET","action":"index","url":"http://localhost:8080/home/index","status":200}.
I don't really get what the prefix represents hence I would like to change that part to show date and timestamps.
Following http://javalite.io/logging#log4j-configuration I should be able to customize the logging via log4j.properties in src/main/resources, but this does not seem to make any difference.
The files content:
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %4p %c{1} - %m%n
I suspect that I have somehow overwritten the default logger, although I did not change anything related in the pom.xml or Main.java.
Am I missing something or could it be that the changes somehow get overwritten?
here is a method I have used on all my JavaLite ActiveWeb projects. The requirements are:
I want to log to a console while development - for convenience.
I want to log to a file in any other environment
I want my log file to have a JSON format because I can analyze it in Splunk, ElasticSearch or any other similar tool.
So, I augmented the ActiveWeb with this commit.
Let's do it step by step:
Add a property to the pom file <logger-name>CONSOLE</logger-name>
Add a file log4j.properties with this content:
```
log4j.rootLogger=INFO, ${logger-name}
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d %4p [%t]: %c{1} - %m%n
log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
log4j.appender.FILE.File=logs/activeweb-simple.log
log4j.appender.FILE.Append=true
log4j.appender.FILE.Encoding=UTF-8
log4j.appender.FILE.layout=org.javalite.logging.JsonLog4jLayout
```
Add an SLF4J dependency to integrate it with Log4J:
```
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
```
Add a profile to the pom:
<profiles>
<profile>
<id>file_log</id>
<properties>
<logger-name>FILE</logger-name>
</properties>
</profile>
</profiles>
Add property filtering to pom:
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
Lets see how this is working.
When you run the program in a development environment without a profile, maven replaces ${logger-name} in your log4j.properties file for CONSOLE. This way, you use the CONSOLE logger, and everything is printed to your console. If you run your program with profile -Pfile_log, then you Maven will replace ${logger-name} with FILE, so Log4J will log to a corresponding file.
Additionally, see that the console layout is org.apache.log4j.ConsoleAppender, but the file layout is org.javalite.logging.JsonLog4jLayout. The org.javalite.logging.JsonLog4jLayout is a JavaLite integration with Log4J built specifically to integrate with Log4J and produce a JSON output.
So, how do you use it? In a development environment you do not need to do anything special, it just works. When you need to build it, run mvn package -Pfile_log -

log4j2 confguration file location when using jetty maven plugin

My application uses log4j2 and we have two of them one for production and another for development environment. I am using maven to run the application using mvn clean jetty:run. My plugin configuration in pom.xml looks like this:
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.8.v20171121</version>
<configuration>
<systemProperties>
<systemProperty>
<name>log4j.configuration</name>
<value>${log4j-dev.location}</value>
</systemProperty>
</systemProperties>
</configuration>
</plugin>
But my app still uses the log4j2.xml present in the WEB-INF/classes directory instead of the one in the log4j-dev.location path. Any ideas?
I found the solution for this problem. In the webdefault.xml file, I had to add the following code:
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>log4j2-custom.xml</param-value>
</context-param>
Hope it helps somebody who spent a whole day looking everywhere like me :)

Using maven jaxb2 plugin, modular compilation using episode and catalog throws Malformed URL error

My project contains A.xsd which imports schema as follows from B.xsd which is part of another project:
<xsd:import namespace="http://com.test.schema/common/Context" schemaLocation="http://com.test.schema/common/Context/B.xsd"/>
I am trying to use the episode from the project which contains B.xsd so that classes related to B.xsd do not get re-generated when A.xsd is parsed. So I referred this and this to come up with the following configuration:
Here is the pom.xml
<dependencies>
<dependency>
<groupId>com.bar.foo</groupId>
<artifactId>schema-b</artifactId>
<version>1.2</version>
</dependency>
<dependencies>
.
.
.
.
.
<build>
<plugins>
<dependency>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.13.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<extension>true</extension>
<episodes>
<episode>
<groupId>com.bar.foo</groupId>
<artifactId>schema-b</artifactId>
</episode>
</episodes>
<catalog>src/main/resources/catalog.cat</catalog>
<schemas>
<schema>
<fileset>
<directory>${basedir}/src/main/schemas</directory>
<includes>
<include>A.xsd</include>
<include>...</include>
<include>...</include>
</includes>
</fileset>
</schema>
</schemas>
<bindingDirectory>${basedir}/src/main/schemas</bindingDirectory>
<bindingIncludes>
<include>*.xjb</include>
</bindingIncludes>
<args>
<arg>-Xannotate</arg>
</args>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.6.0</version>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics-annotate</artifactId>
<version>0.6.0</version>
</plugin>
</plugins>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Here is the catalog file:
PUBLIC "http://com.test.schema/common/Context" "maven:com.bar.foo:schema-a:jar::1.2!"
There is some configuration in the xjb file to make sure that XmlRootElement is written into some generated classes:
<jxb:bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
jxb:version="2.1" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:annox="http://annox.dev.java.net" extensionBindingPrefixes="xjc">
<jxb:globalBindings>
<xjc:simple />
</jxb:globalBindings>
<jxb:bindings
schemaLocation="A.xsd">
<jxb:bindings node="//xsd:complexType[#name='ADataType']">
<jxb:class name="AData" />
<annox:annotate>
<annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
name="AData" />
</annox:annotate>
</jxb:bindings>
</jxb:bindings>
Inspite of providing the episode to the xjc execution and the location of the schema for B.xsd in the catalog file, the classes for B.xsd is getting generated.
The issue is that the maven artifact referred to by the catalog file is not being picked up. I see the following error in the maven build logs:
Malformed URL on system identifier: maven:com.bar.foo:schema-b:jar::1.2!
PUBLIC: http://com.test.schema/common/Context
maven:com.bar.foo:schema-a:jar::1.2!
Can anyone help tell me why am I hitting this malformed URL error for the artifact that contains B.xsd? Any help will be really appreciated.
Disclaimer: I'm the author of the maven-jaxb2-plugin.
First, you're probably mixing A and B here. You're saying A imports B but then you're using the schema-a artifact as episode. If B is imported, you should use schema-b as episode to not regenerate B stuff when compiling A.
But I think this is probably just a minor mistake in the question.
You have two aspects here - episodes and catalogs.
Episodes allow you to skip generation of classes you've generated somewhere else already. So if you use schema-b artifact when compiling schema-a then XJC should not generate classes for schema-b. You don't need catalogs for that, it's independent.
Sometimes XJC still generates few leftovers - even if you use an episode. I often get ObjectFactory and maybe some enums or top-level-elements generated. I believe this is an issue in XJC, there's nothing I can do in the maven-jaxb2-plugin about it.
So as a workaround I just use maven-antrun-plugin to delete unnecessary generated things.
If you get all of the B stuff generated then you should check if schema-b artifact really have the episode file generated. Check if you have META-INF/sun-jaxb.episode inside the JAR. See this answer for some trivia on the episode file.
So if you correctly configure the correct episode artifact you should not get B things generated, you don't need catalogs for this.
What you need the catalog for is to avoid downloading http://com.test.schema/common/Context/B.xsd when compiling. You can use catalogs to point to anothe location. I think your problem here is that you refer http://com.test.schema/common/Context to maven:com.bar.foo:schema-a:jar::1.2! which obviously does not point to the schema resource.
If you have an import like
<xsd:import namespace="http://com.test.schema/common/Context" schemaLocation="http://com.test.schema/common/Context/B.xsd"/>
Then you should probably rewrite it as follows:
PUBLIC "http://com.test.schema/common/Context" "maven:com.bar.foo:schema-b:jar::1.2!/common/Context/B.xsd"
Assuming schema-b artifact contains your schema under /common/Context/B.xsd. Note that it maps namespace, not schema location.
You can also use REWRITE_SYSTEM to rewrite schema location. For example:
REWRITE_SYSTEM "http://com.test.schema" "maven:com.bar.foo:schema-b:jar::1.2!"
If you have an URL like http://com.test.schema/common/Context/B.xsd, it will be rewritten to maven:com.bar.foo:schema-b:jar::1.2!/common/Context/B.xsd. This will point to the resource /common/Context/B.xsd inside your schema-b JAR.
Another hint - if you use schema-b as dependency in your project, you can omit the version.
Here's an example of catalog from a real world project:
https://github.com/highsource/ogc-schemas/blob/master/schemas/src/main/resources/ogc/catalog.cat
It contains rewrites like:
REWRITE_SYSTEM "http://schemas.opengis.net" "maven:org.jvnet.ogc:ogc-schemas:jar::!/ogc"

Using log4j with JBoss 7.1

How can I use log4j with JBoss 7.1?
I have a log4j-1.2.16.jar in my WebContent/WEB-INF/lib folder. When I output the result of Logger.getRootLogger().getClass().toString() I get class org.jboss.logmanager.log4j.BridgeLogger which is wrong.
If I add Dependencies: org.apache.commons.logging to my MANIFEST.MF file I get the same result.
This results into the problem that my log4j.properties file (which I created unter WEB-INF/classes) is ignored.
There will soon be a way that will just work for you, but currently you have to exclude the log4j dependency from your deployment. You will also have to manually invoke the PropertyConfigurator.configure() to load the properties file.
The following file (jboss-deployment-structure.xml) needs to contain the following:
<jboss-deployment-structure>
<deployment>
<!-- Exclusions allow you to prevent the server from automatically adding some dependencies -->
<exclusions>
<module name="org.apache.log4j" />
</exclusions>
</deployment>
</jboss-deployment-structure>
Then adding including your own version of log4j in the WEB-INF/lib directory should work as you expect it to.

Resources