Izpack: Creating custom panels - java

I am trying to create a custom panel for an IzPack installer. This means that I have to extend IzPanel. However, it appears that if I do this, the extended panel needs to be in the com.izforge.izpack.panels package.
Then I found this post, which stipulates that:
As such, you must include installer.jar from the lib folder of IzPack in the build path of your custom panel project.
Your custom panel /must/ extend com.izforge.izpack.installer.IzPanel.
Furthermore, it /must/ reside in the com.izforge.izpack.panels package.
On top of it all, your build jar's name /must/ be the same as the
unqualified name of your custom panel class.
I take issue with the 1st and 4th points. They imply that I have to create an additional JAR file for each custom IzPanel that I create. Also, I would have to modify the IzPack installation by adding these JARs to one of its subdirectories.
Is this article outdated (2008) and can it be safely ignored, or is this still true?
If not how can I avoid this and simply have the extended IzPanel on the classpath instead?
Thank you!

Okay, I take it you want to have your panels in a single jar within your own package.
This is how you do it:
Create your jar with all of your custom panels
Copy that jar to the IzPackStagingFolder\bin\panels
Edit the installer descriptor and under the panels sections reference your CustomPanels.jar
Then inside your install.xml you define your panels sections similar to:
...
<panels>
<panel classname="HTMLInfoPanel" id="infopanel" encoding="ISO-8859-1" />
<panel classname="TargetPanel" id="targetpanel" />
<panel classname="com.myCompany.installer.panels.MyCustomPanelOne" id="customPanelOne" jar="bin/panels/CustomPanels.jar" />
<panel classname="UserInputPanel" id="userInputPanel" />
<panel classname="InstallPanel" id="installPanel" />
<panel classname="ProcessPanel" id="processPanel" />
<panel classname="com.myCompany.installer.panels.MyCustomPanelTwo" id="customPanelTwo" jar="bin/panels/CustomPanels.jar" />
<panel classname="FinishPanel" id="finishPanel" />
</panels>
...
Where CustomPanels.jar can be a single maven project with your own panels in your own package with two classes CustomPanelOne and CustomPanelTwo both extending IzPanel.
For more info see IzPack's older 4.x documentation at https://izpack.atlassian.net/wiki/spaces/IZPACK/pages/491534/Creating+Panels. As of right now the newer IzPack 5.x doc wiki is missing this section.
Also reffer to the XML DTD at https://github.com/izpack/izpack/blob/4.3/src/dtd/installation.dtd

One more point in addition to Paul Bors answer here.
IzPacks 4.x needed only installer.jar as dependency. When i first tried to compile the custom panel with installer.jar (izpack-installer-5.0.0-beta11.jar), found many compilation errors. Izpack 5.0 adds additional dependency on IzPack api (izpack-api-5.0.0-beta11.jar) and Izpack gui(izpack-gui-5.0.0-beta11.jar).
Enjoy creating custom panels.

Related

Choose one dependency as precedent over another for an arbitrary list of packages in the IntelliJ Builder

Goal
I'm trying to make my maven project use the IntelliJ builder when I'm editing code because the IDE offers fast rebuild and hot deployment features that could speed up my work. However I'm running into a roadblock due to how my maven project is set up.
Constraints
I have to use maven the way it's being used. The solution must be in IntelliJ
Note that creating an IntelliJ plugin is an option. I realize this may be necessary due to the limitations of IntelliJ build configuration.
The problem
My project depends on 2 libraries, SharedLibA and SharedLibB, which contain package com.shared. SharedLibA is a new library, and sharedLibB is and old legacy one. SharedLibA and SharedLibB contain packages that are not contained in the other, which are needed by my project. The package they both have, com.shared is needed by the project too. However SharedLibB is legacy/old so we always want Tomcat to prioritize the implementation of classes in com.shared from SharedLibA, not the implementations of those classes in SharedLibB. We accomplish this by having a maven goal that extracts classes under package com.shared from SharedLibA to WEB-INF/classes when the WAR is packaged.
When I try to build my project in IntelliJ, it picks up the wrong implementation of classes in com.shared.* and spews out compilation errors despite compilation working perfectly via maven. I'm stuck with this inflexible maven hackjob but I still want to find a way to make IntelliJ understand that I want SharedLibA's com.shared.* classes to be used in compilation not SharedLibB's. I can't remove SharedLibB from consideration because I need the other classes in SharedLibB to compile my project.
Desired Solution
I'm looking for some kind of logic like "when com.shared.* classes are considered, choose SharedLibA" or "when any package conflict happens in classpath resolution, prioritize ShareLibA" because I'm pretty sure SharedLibA should be prioritized in any package conflict.
Thanks
I hope that explains it well enough, thank you in advance to anyone who chimes in here.
IDE builds the classpath and buildpath based on the dependencies which are configured for the module. It also considers their order - the 1st dependency that match given class will be used.
For Maven-based projects the dependencies list and their order IDE takes from the Maven pom.xml file of the module. So you can set the order in pom.xml file.
Another mentioned option is to exclude the library items. But the better solution would be to configure Maven build properly.
You should try to go to your project ".IML" file and there :
you can create or modify a module.
In there you can include or exclude the libs or defining its use priority
you could use this snippet to inspire
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="8">
<component name="SharedB" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
...
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
...
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
...
</component>
</module>
if you are not confortable with this solution you could use the module settings of Intellij
https://www.jetbrains.com/help/idea/library.html#excluded_lib_items

Solr - How to use "dir" attribute of <lib> tag, in solrconfig.xml

I tried to use the DIH feature of solr, but the <lib> tag in solrconfig.xml confused me a little.
Paths:
I install solr under solr_5.2.1\.
Core is created at solr_5.2.1\server\solr\search_cn\
solrconfig.xml is at solr_5.2.1\server\solr\search_cn\conf\solrconfig.xml
DIH lib is at solr_5.2.1\dist\solr-dataimporthandler-5.2.1.jar
I thought following <lib> should be used to import DIH lib:
<lib dir="../../../../dist/" regex="solr-dataimporthandler-\d.*\.jar" />
But, it don't, instead, following works:
<lib dir="../../../dist/" regex="solr-dataimporthandler-\d.*\.jar" />
Any one can help to explain about that? Thx.
#Update:
If the answer by #abhishek bafna is correct, then I have another doubt:
When I create a lib folder at: solr_5.2.1\server\solr\search_cn\lib\.
And include it via <lib dir="../lib/" />, it could found the jars inside.
But according to the answer, it should be <lib dir="./lib/" />, right?
Could you help to explain that, I want to make it clear to avoid future config issue, thx.
#Summary:
I did a test according to answer of #abhishek bafna.
And following is my summary, (with solr 5.2.1):
<lib>'s dir is relative to instance_dir, where the solr.properties is found.
by default instance_dir_base/lib/ will be searched to find jars, and no need to config it via <lib>.
any other folder, need to use a <lib> to config properly, if want to load jars from it.
The directories are resolved relative to solr instanceDir. The instanceDir is place where it founds the core.properties file. It looks for a conf folder inside the instanceDir and creates the data (index data) directory.

org.talend cannot be resolved

I downloaded one custom Talend component from Talend exchange. When I tried to run a job using this component, it gives org.talend cannot be resolved error. The component has required jars along with custComponent_message.properties, custComponent_begin.jet, custComponent_java.xml, custComponent.png files inside it. The CODEGENERATION part of custComponent_java.xml looks like this
<CODEGENERATION>
<IMPORTS>
<IMPORT NAME="bcprovider" MODULE="bcprov-jdk16-143.jar" REQUIRED="true" />
<IMPORT NAME="bcpg" MODULE="bcpg-jdk16-143.jar" REQUIRED="true" />
<IMPORT NAME="PGPEncrypt" MODULE="PGPEncrypt.jar" REQUIRED="true" />
</IMPORTS>
</CODEGENERATION>
Inside custComponent_begin.javajet there is this line that's where I am getting org.talend cannot be resolved error.
org.talend.pgp.PGPEncrypt.encryptFile(<%=source%>,<%=destination%>,<%=publicKey%>,<%=remove%>);
What am I doing wrong here? Do I need to save the jars in some other location too? Please help
The procedure for installing custom components is described here: https://help.talend.com/display/KB/How+to+install+external+modules+in+the+Talend+products
In essence, you should go to the Modules view (Window > Show views > Talend > Modules) and download and install needed modules from there.

How to automate GWT builds using different sets of property values?

I need to be able to build two different versions of my GWT application using two different sets of property values. For example, one version would be built with the value of custom_property set to "A" and another would be built with the value of custom_property set to "B".
Currently I am editing the application's module XML file in between builds by hand. So, to make one build I would first add:
<set-property name="custom_property" value="A"/>
And to make the other build I would change this line to:
<set-property name="custom_property" value="B"/>
This approach is working okay, but I would like to automate it if possible.
Is there a good way to accomplish this?
One powerful way to do this would be using Maven substitution. I've used this approach in many GWT- and non-GWT-based apps. Due to Maven's prevalence, you'll find loads of examples of Mavenizing your GWT app. Then you can use Maven substitution to make all the magic happen.
You can clone your app's module XML file and change values of your custom properties in it (e.g. MyAppStaging.gwt.xml and MyAppProd.gwt.xml). You'll thus be able to script builds of different app versions and have different run configurations in your IDE. The drawback here is in subsequently needing to maintain both module XML files.
Building on #BorisBrudnoy's idea of multiple module XML files, I placed all module XML that was not related to setting the properties that differ between builds in a MyAppBase.gwt.xml file. I then created MyAppA.gwt.xml with:
<module rename-to="myappA">
<inherits name="com.mycompany.MyAppBase"/>
<set-property name="custom_property" value="A"/>
</module>
and MyAppB.gwt.xml with:
<module rename-to="myappB">
<inherits name="com.mycompany.MyAppBase"/>
<set-property name="custom_property" value="B"/>
</module>
Now I can specify either com.mycompany.MyAppA or com.mycompany.MyAppB on the GWT compile command line, and there is no replication of configuration.

Can I create a custom classpath on a per application basis in Tomcat

For some applications I use ZK, others Hibernate, other Apache Commons, etc.
I don't want to deploy a 75MB war file, just because it uses lots of libraries.
I don't want to add the libraries to my tomcat lib folder, or nor the classpath to it's configuration as I may have an old application using library x.1 and another application using library x.2
For this reason, it would be great to have something in the web.xml or context.xml where I say something like:
<classpath>/usr/local/tomcat/custom-libs/zk-5.0.4</classpath>
Note: The above is pseudo-code
From Tomcat 7 there is no mention of not being able to use the VirtualWebappLoader in production. I tried it and it works like a dream. Simply add the following to META-INF/context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/websandbox">
<Loader className="org.apache.catalina.loader.VirtualWebappLoader"
virtualClasspath="/usr/.../*.jar;/usr/.../*.jar"/>
</Context>
In Netbeans, under packaging, I just untick all the packages, taking the .war size down to nothing, make sure the dependencies are in the correct folders on the server and upload. Yey! No more 100 MB WAR file.
Addition #Spider answer.
Tomcat Context hold Loader element. According to docs deployment descriptor (what in <Context> tag) can be placed in:
$CATALINA_BASE/conf/server.xml - bad - require server restarts in order to reread config
$CATALINA_BASE/conf/context.xml - bad - shared across all applications
$CATALINA_BASE/work/$APP.war:/META-INF/context.xml - bad - require repackaging in order to change config
$CATALINA_BASE/work/[enginename]/[hostname]/$APP/META-INF/context.xml - nice, but see last option!!
$CATALINA_BASE/webapps/$APP/META-INF/context.xml - nice, but see last option!!
$CATALINA_BASE/conf/[enginename]/[hostname]/$APP.xml - best - completely out of application and automatically scanned for changes!!!
Here my config which demonstrate how to use development version of project files out of $CATALINA_BASE hierarchy (note that I place this file into src/test/resources dir and intruct Maven to preprocess ${basedir} placeholders through pom.xml <filtering>true</filtering> so after build in new environment I copy it to $CATALINA_BASE/conf/Catalina/localhost/$APP.xml):
<Context docBase="${basedir}/src/main/webapp"
reloadable="true">
<!-- http://tomcat.apache.org/tomcat-7.0-doc/config/context.html -->
<Resources className="org.apache.naming.resources.VirtualDirContext"
extraResourcePaths="/WEB-INF/classes=${basedir}/target/classes,/WEB-INF/lib=${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
<Loader className="org.apache.catalina.loader.VirtualWebappLoader"
virtualClasspath="${basedir}/target/classes;${basedir}/target/${project.build.finalName}/WEB-INF/lib"/>
<JarScanner scanAllDirectories="true"/>
<!-- Use development version of JS/CSS files. -->
<Parameter name="min" value="dev"/>
<Environment name="app.devel.ldap" value="USER" type="java.lang.String" override="true"/>
<Environment name="app.devel.permitAll" value="true" type="java.lang.String" override="true"/>
</Context>
UPDATE Tomcat 8 change syntax for <Resources> and <Loader> elements, corresponding part now look like:
<Resources>
<PostResources className="org.apache.catalina.webresources.DirResourceSet"
webAppMount="/WEB-INF/classes" base="${basedir}/target/classes" />
<PostResources className="org.apache.catalina.webresources.DirResourceSet"
webAppMount="/WEB-INF/lib" base="${basedir}/target/${project.build.finalName}/WEB-INF/lib" />
</Resources>
Another a bit hacky alternative.
You can write a 5-6 line custom class loader which derives from urlclassloader, and simply adds your classpath jars using addUrl() method.
Then set it as the context class loader of the thread in your application code.
Thread.setContextClassLoader(new CustomClassloader(path, parentClassLoader)
where parent class loader typically is
Thread.getContextClassloader()
This is what the META-INF/context.xml file can be used for. You defined your own WebappLoader, which loads classes for your particular webapp. This is the reference I used: http://tomcat.apache.org/tomcat-5.5-doc/config/loader.html (Edit: for Tomcat 6: http://tomcat.apache.org/tomcat-6.0-doc/config/loader.html, for Tomcat 7: http://tomcat.apache.org/tomcat-7.0-doc/config/loader.html)
Also this fellow here seems to post a solution to your exact problem (example included): http://java.dzone.com/articles/extending-tomcat-webapploader

Categories