I maintain an Eclipse RCP application launched with WebStart. Java 7 u45 made some security changes, and now my application crashes on startup.
I've added to the manifest:
Permissions: all-permissions
Codebase: *
Trusted-Library: true
This removed all of the warning messages from the Control Panel. But I still have a classloader issue when trying to load my IApplication implemenentation, probably the first of my classes to load. This is new to update 45.
I have experienced the same issue and managed to solve it by doing following:
In all manifest files (for each JAR in your RCP project) add these attributes:
Application-Name: My App Name
Permissions: all-permissions
Codebase: *
Application-Library-Allowable-Codebase: *
Caller-Allowable-Codebase: *
Trusted-Library: true
Second part of solution is to make jnlp properties secure by adding jnlp prefix. I have found solution here. You need to do this for framework properties (osgi, eclipse..) and for your properties E.g. instead of:
<property name="eclipse.product" value="com.amdosoft.oct.ui.product"/>
<property name="osgi.instance.area" value="#user.home/Application Data/myApp"/>
<property name="osgi.configuration.area" value="#user.home/Application Data/myApp"/>
<property name="my.App.property" value="someValue"/>
use
<property name="jnlp.eclipse.product" value="com.amdosoft.oct.ui.product"/>
<property name="jnlp.osgi.instance.area" value="#user.home/Application Data/myApp"/>
<property name="jnlp.osgi.configuration.area" value="#user.home/Application Data/myApp"/>
<property name="jnlp.my.App.property" value="someValue"/>
Download eclipse launcher with sources from here
In web start launcher you need to change back property names to old values (without jnlp prefix). You can do that by adding this part of source into main method of WebStartLauncher class.
Properties properties = System.getProperties();
// copy properties to avoid ConcurrentModificationException
Properties copiedProperties = new Properties();
copiedProperties.putAll(properties);
Set<Object> keys = copiedProperties.keySet();
for (Object key : keys) {
if (key instanceof String) {
String keyString = (String) key;
if (keyString.startsWith("jnlp.")) {
// re set all properties starting with the jnlp-prefix
// and set them without the prefix
String property = System.getProperty(keyString);
String replacedKeyString = keyString.replaceFirst("jnlp.", "");
System.setProperty(replacedKeyString, property);
}
}
}
Export you new launcher as runnable JAR and put it in the same directory where your JNLP file is located.
Edit JNLP file by adding this line:
<jar href="myAppLauncher.jar"/>
inside tag and edit your application-desc tag like this:
<application-desc main-class="org.eclipse.equinox.launcher.WebStartMain">
</application-desc>
When 7u25 came out, my application would crash with a classloader issue (sometimes, it was weird). The fix involved nixing my "Components.jnlp" deployment strategy. I had my library files in a separate .jnlp (Components.jnlp, as per a solution I read online back in 2010) and my main .jnlp (launch.jnlp) would load that .jnlp.
Now, it seems the Netbeans-generated .jnlp is sufficient and I no longer need any separate .jnlp for library components. I'm not sure if eclipse gives you an auto-generated .jnlp or not.
In the end, changing the launch.jnlp involved me having to give my clients a new installer that would load the new .jnlp onto their computers. It sucked but it worked.
Also, I'm not sure what Codebase: * is supposed to do. Why don't you just put your actual codebase in there?
If you did not deploy your app with that approach then this answer probably won't help. Might help somebody.
We've had multiple JNLP files up until now, and it seemed to work.
We install our app on customer internal networks, so we can't set a codebase other than * without resigning the entire set of jars for each customer.
Related
We are migrating our application from WAS 6.1 to Liberty. Our application uses third party jars that read property files byInputStream is = ClassLoader.getSystemResource("myproperty.properties").
In WAS 6.1, we set server classpath to the location of myproperty.properties. We tried the below approaches to set classpath in Liberty, but nothing works
Approach 1: Set the below in jvm.options (D:\ConfigFiles\DEV\ - path containing myproperty.properties)
-Djava.class.path=D:\\ConfigFiles\\DEV\\
Approach 2: Setting the classloader in server.xml,
<library id="config">
<folder dir="${server.config.dir}/config/" includes="*.properties" scanInterval="5s"/>
</library>
<enterpriseApplication id="applicationEAR" location="application.ear" name="application">
<classloader privateLibraryRef="config"/>
</enterpriseApplication>
Please let us know if there is any other ways to override/set classpath in Liberty profile?
Try setting this property in jvm.options (instead of -Djava.class.path=path/to/propertyDir):
-Xbootclasspath/a:path/to/propertyDir
This will append the path of the property directory (containing your resource file) to the JVM's bootstrap classpath. Because this is an append, it should also work in Java 9+ (some related options have been removed in Java 9).
I suspect that the reason -Djava.class.path=... doesn't work is that the JVM gets the classpath from the WLP server script - so the system property is essentially applied too late in the startup of the server JVM.
You might also be able to put the properties file(s) in your JVM's lib/ext directory, but I haven't tested that. The -Xbootclasspath/a:path approach works for me on Mac - I assume it will also work on Windows.
HTH, Andy
If your end goal is to load a properties file, a more straightforward way to do this would be using a bootstrap/env/system property or <jndiEntry> in server.xml to store the location of the properties file, and then load it. For example, using an environment variable:
(in server.xml file)
<server>
<featureManager>
<feature>jndi-1.0</feature>
...
</featureManager>
<jndiEntry jndiName="configDir" value="D:\\ConfigFiles\\Dev"/>
</server>
Then, you can load the resource in your application like this:
#Resource(lookup = "configDir")
String configDir;
InputStream is = new FileInputStream(configDir + "/myproperty.properties");
Or, if you will always put your config property files somewhere under ${server.config.dir}, then you can utilize the built-in SERVER_CONFIG_DIR environment variable in Liberty:
String configDir = System.getenv("SERVER_CONFIG_DIR"); // equivalent to ${server.config.dir} in server.xml
InputStream is = new FileInputStream(configDir + "/myproperty.properties");
On the topic of managing configuration, check out MicroProfile Config (e.g. <feature>microProfile-1.2</feature>) which you may find useful: Configuring microservices with Liberty
This question already has answers here:
With Java 7 Update 45, the System Properties no Longer Set from JNLP Tag "Property"
(5 answers)
Closed 9 years ago.
With the new Java 7 update 45, we are not able to set properties. We used to set it as follows
<resources>
...
<jar href="xxx.jar"/>
<property name="xxx.xxx.xxx.xxx.userName" value="Batman"/>
<property name="xxx.xxx.xxx.xxx.locale" value="en_US"/>
...
</resources>
We tried the work around, tried the following
<resources>
...
<jar href="xxx.jar"/>
<property name="jnlp.xxx.xxx.xxx.xxx.userName" value="Batman"/>
<property name="jnlp.xxx.xxx.xxx.xxx.locale" value="en_US"/>
...
</resources>
even tried "javaws." added as prefix.
Problem is we that we want to avoid making change in the codebase and want to fix the issue in the jnlp level.
Do we have any other work around or any ideas?
According to this OpenJDK bug report (https://bugs.openjdk.java.net/browse/JDK-8023821) there are three possible workarounds:
Sign the jnlp file.
Use either a signed-jnlp file (JNLP-INF/APPLICATION.JNLP) or a signed jnlp template (JNLP-INF/APPLICATION_TEMPLATE.JNLP).
Use secure properties.
Change all the properties in the jnlp file to pre-pend "jnlp." to the property name, and modify all code to use the new properties name.
Use secure properties and translate them in the main of your signed application to insecure properties.
Change jnlp files to have the property names in the jnlp file pre-pended with "jnlp.myapp.", then in your application read the system properties and for each property starting with "jnlp.myapp." set the corresponding property without the "jnlp.myapp." pre-pended to the name.
It sounds like 2 and 3 are not what you want. So that leaves you with option 1. (Or accept that you need to change your codebase.)
I'm working in a Java Web Project.
I need to change the folder of the files "jdbc.properties" and "log4j.properties" depending of the environment, because testing, demo and release have diferent values for those files.
I have this folders and subfolders:
c:\myProject\conf\dev
c:\myProject\conf\test
c:\myProject\conf\demo
I need to put diferent jdbc.properties and log4j.properties files in each of those folders
c:\myProject\conf\dev\log4j.properties
c:\myProject\conf\dev\jdbc.properties
c:\myProject\conf\test\log4j.properties
c:\myProject\conf\test\jdbc.properties
c:\myProject\conf\demo\log4j.properties
c:\myProject\conf\demo\jdbc.properties
The three project are in the same Server and in the same Apache (It is a Web Project)
First i made some changes to use a windows system variable to get the parent folder (c:\myProject). To do that, i made this on Spring appContext file:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>file:${PARENT_FOLDER}/conf/dev/jdbc.properties</value>
</property>
</bean>
"PARENT_FOLDER" is defined on Windows environment variables/system variable
Those changes works OK.
But, as you can see, I always loking for file on "/conf/dev"
I need to make dynamic the "dev" part of the path.
I Can't use Windows environment variables/system variable because the 3 environments are deployed on the same Server.
I'm trying to use a "property" (using ) on web.xml, but I don't know how to find the property in my Spring appContext file.
I definy the property like this:
<env-entry>
<env-entry-name>ENVIRONMENT</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>Dev</env-entry-value>
</env-entry>
But I don't know how to access "ENVIRONMENT" property on Spring
I don't know what to do. I a little desperate
Can someone help me?
Thanks and sorry for my poor english
Have you considered using JNDI?
With JNDI you will define the db connection properties inside tomcat itself. This way your spring configuration is independent of the environment and you can deploy the same war on all environments. See also this.
If you need to run it locally that you can always use the 'new' spring environment profiles feature.
Other option (if JNDI is not an option and assuming you use maven) is the maven replacer plugin where you will generate the db.properties at build time.
I have a JEE application that runs on WAS 6. It needs to have the class loader order setting to "Classes loaded with application class loader first", and the WAR class loader policy option set to "Single class loader for application".
Is it possible to specify these options inside the EAR file, whether in the ibm-web-bnd.xmi file or some other file, so the admin doesn't need to change these setting manually?
Since the app is deployed via an automated script, and the guy who is in charge of deployment is off site, and also for some other political reasons, this would greatly help!
Thanks to #Matthew Murdoch's answer, I was able to come up with a solution. Here it is, in case it helps someone else.
I created a deployment.xml like this:
<?xml version="1.0" encoding="UTF-8"?>
<appdeployment:Deployment xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:appdeployment="http://www.ibm.com/websphere/appserver/schemas/5.0/appdeployment.xmi" xmi:id="Deployment_1241112964096">
<deployedObject xmi:type="appdeployment:ApplicationDeployment" xmi:id="ApplicationDeployment_1241112964096" startingWeight="1" warClassLoaderPolicy="SINGLE">
<classloader xmi:id="Classloader_1241112964096" mode="PARENT_LAST"/>
<modules xmi:type="appdeployment:WebModuleDeployment" xmi:id="WebModuleDeployment_1241112964096" startingWeight="10000" uri="AGS.war">
<classloader xmi:id="Classloader_1241112964097"/>
</modules>
</deployedObject>
</appdeployment:Deployment>
Make sure to change the name of your WAR file(s) to match (mine is called AGS.war).
I also changed the numbers in the xmi:id attributes, to be sure they are unique, though I'm not sure it it really matters that they be unique across applications.
Then, I put the deployment.xml file in the root of my EAR file, via ANT:
<ear destfile="${artifactsDir}/${earName}.ear" appxml="${projectName}_EAR/application.xml">
<fileset dir="${artifactsDir}" includes="${warName}.war"/>
<fileset dir="${projectName}_EAR/" includes="deployment.xml"/>
</ear>
Edit (2): The WebSphere Application Server Toolkit (AST) is a tool you can use to enhance an EAR file with this information (see for example the 'Configure an Enhanced EAR' section in this document).
Edit (1): This post suggests that the 'Classes loaded with application class loader first' (the PARENT_LAST setting) can be set in the deployment.xml file within the EAR.
If you have control over the automated deployment scripts this can be done. Below is some wsadmin jython code for setting the web module class loader order to 'Classes loaded with application class loader first' (interestingly the setting is called PARENT_LAST which is what it was labelled in previous versions of the admin console...).
wsadmin example (jython):
def getWebModule(config, applicationName):
webModules = config.list('WebModuleDeployment').
split(system.getProperty('line.separator'))
for webModule in webModules:
if (webModule.find(applicationName) != -1):
return webModule
return None
applicationName = "<Your application name here>"
webModule = getWebModule(AdminConfig, applicationName)
if (webModule != None):
AdminConfig.modify(webModule, "[[classloaderMode PARENT_LAST]]")
AdminConfig.save()
else:
print "Error: Cannot find web module for application: " + applicationName
Check out this link. There are different ways to set class loader policy using Jython based on your server version -
http://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=%2Fcom.ibm.websphere.express.doc%2Finfo%2Fexp%2Fae%2Frxml_7libapp4.html
Similar to the answer from pkaeding, I discovered as follows, not specific to a particular .war by name, but useful when applying to whatever is the default .war in the .ear file. (.ear files with one .war file in them have only that .war, so naming the .war isn't necessary in the entry.) This approach may be good for situations where you may need to re-name of the .war project later for some reason, and so you wouldn't need to worry about updating the deployment.xml file. I found the deployment.xml file buried inside a cell reference directory trail; dunno if it's fine as shown when the file is placed at directory level META-INF and no deeper.
In my particular case, I found deployment.xml in my .ear project at:
<project_root>\META-INF\ibmconfig\cells\defaultCell\applications\defaultApp\deployments\defaultApp\
The content of the file looks a lot like:
<appdeployment:Deployment xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
xmlns:appdeployment="http://www.ibm.com/websphere/appserver/schemas/5.0/appdeployment.xmi" xmi:id="Deployment_1262775196208">
<deployedObject xmi:type="appdeployment:ApplicationDeployment"
xmi:id="ApplicationDeployment_1262775196208" startingWeight="10">
<classloader xmi:id="Classloader_1262775196208" mode="PARENT_LAST" />
</deployedObject>
</appdeployment:Deployment>
The line:
<classloader xmi:id="Classloader_1262775196208" mode="PARENT_LAST" />
originally read:
<classloader xmi:id="Classloader_1262775196208" mode="PARENT_FIRST" />
Note no reference to any .war is being made. As pkaeding mentioned, you shouldn't expect the various id numbers to be the same for you.
Here's another issues that we are facing while migrating our application from current production environment to the new data center environment (see details below)
Current Production Environment : Java 1.4, Java EE 3, WAS 5.1, JSF 2.1
New Environment: Java 1.5, Java EE 5, WAS 6.1, JSF 2.1
Here we have a third party jar file with the following structure (check the image - pardon me hiding some details)
This class has the code to load the database properties from a ResourceBundle (db.properties). Here is the code rendered out by Cavaj:
private static ResourceBundle getDBProperties()
{
if(dbProperties == null)
{
dbProperties = ResourceBundle.getBundle("db");
}
return dbProperties;
}
This application is working fine on the current environment. But somehow when we move the application to the new environment we get a "MissingResourceException" (see below):
Caused by: java.util.MissingResourceException: Can't find bundle for
base name db, locale en_US
at
java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:863)
at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:832)
at java.util.ResourceBundle.getBundle(ResourceBundle.java:576)
at
com.myco.wo.vs.util.OrderLovUtilities.getDBProperties(OrderLovUtilities.java:195)
We tried following workarounds but none worked:
Renamed the db.properties as db_en_US.properties
Putting the properties file in the jar
moving the jar file at EAR level.
Please suggest on what could be wrong here. And what can we do to get it working :)
Note: File db.properties is located under the WEB-INF/classes directory. Also we tried putting it on the above mentioned locations but to no avail.
Regards,
- Ashish
Try to change classloader ordering in settings of your ent. application in the admin console (from PARENT_FIRST to PARENT_LAST) on both EAR and WAR levels.
It seems to me that 3rd party class (com.myco.wo.vs.util.OrderLovUtilities) is not loaded from your jar file in WEB-INF/lib, but it is rather comes from some other location on the server. Its classloader then does not see the property file.
If that is the issue, changing the classloader ordering should cause the expected copy of the class to load.
Also, the classloader viewer in the admin console can put some light on that.
Have you tried putting your db.properties file under WEB-INF/classes directory?