blob: 6082f3af465326f40416aa61c5785a49a1517dd5 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.autoupdate.updateprovider;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Stack;
import java.util.TreeSet;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.netbeans.modules.autoupdate.services.Trampoline;
import org.netbeans.modules.autoupdate.services.UpdateLicenseImpl;
import org.netbeans.modules.autoupdate.services.Utilities;
import org.netbeans.spi.autoupdate.UpdateItem;
import org.netbeans.spi.autoupdate.UpdateLicense;
import org.netbeans.updater.XMLUtil;
import org.openide.util.Exceptions;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.Attributes;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
*
* @author Jiri Rechtacek
*/
public class AutoupdateInfoParser extends DefaultHandler {
private static final String INFO_NAME = "info";
private static final String INFO_EXT = ".xml";
private static final String INFO_FILE = INFO_NAME + INFO_EXT;
private static final String INFO_DIR = "Info";
private static final String INFO_LOCALE = "locale";
private final Map<String, UpdateItem> items;
private final EntityResolver entityResolver;
private final File nbmFile;
private UpdateLicenseImpl currentUpdateLicenseImpl;
private AutoupdateInfoParser (Map<String, UpdateItem> items, File nbmFile) {
this.items = items;
this.entityResolver = newEntityResolver();
this.nbmFile = nbmFile;
}
private EntityResolver newEntityResolver () {
try {
Class.forName("org.netbeans.updater.XMLUtil");
} catch (ClassNotFoundException e) {
final File netbeansHomeFile = new File(System.getProperty("netbeans.home"));
final File userdir = new File(System.getProperty("netbeans.user"));
final String updaterPath = "modules/ext/updater.jar";
final String newUpdaterPath = "update/new_updater/updater.jar";
final File updaterPlatform = new File(netbeansHomeFile, updaterPath);
final File updaterUserdir = new File(userdir, updaterPath);
final File newUpdaterPlatform = new File(netbeansHomeFile, newUpdaterPath);
final File newUpdaterUserdir = new File(userdir, newUpdaterPath);
String message =
" org.netbeans.updater.XMLUtil is not accessible\n" +
" platform dir = " + netbeansHomeFile.getAbsolutePath() + "\n" +
" userdir dir = " + userdir.getAbsolutePath() + "\n" +
" updater in platform exist = " + updaterPlatform.exists() + (updaterPlatform.exists() ? (", length = " + updaterPlatform.length() + " bytes") : "") + "\n" +
" updater in userdir exist = " + updaterUserdir.exists() + (updaterUserdir.exists() ? (", length = " + updaterUserdir.length() + " bytes") : "") + "\n" +
" new updater in platform exist = " + newUpdaterPlatform.exists() + (newUpdaterPlatform.exists() ? (", length = " + newUpdaterPlatform.length() + " bytes") : "") + "\n" +
" new updater in userdir exist = " + newUpdaterUserdir.exists() + (newUpdaterUserdir.exists() ? (", length = " + newUpdaterUserdir.length() + " bytes") : "") + "\n";
ERR.log(Level.WARNING, message);
}
return org.netbeans.updater.XMLUtil.createAUResolver ();
}
private static final Logger ERR = Logger.getLogger (AutoupdateInfoParser.class.getName ());
private static enum ELEMENTS {
module, description,
module_notification, external_package, manifest, l10n, license
}
private static final String LICENSE_ATTR_NAME = "name";
private static final String MODULE_ATTR_CODE_NAME_BASE = "codenamebase";
private static final String MODULE_ATTR_HOMEPAGE = "homepage";
private static final String MODULE_ATTR_DOWNLOAD_SIZE = "downloadsize";
private static final String MODULE_ATTR_NEEDS_RESTART = "needsrestart";
private static final String MODULE_ATTR_MODULE_AUTHOR = "moduleauthor";
private static final String MODULE_ATTR_RELEASE_DATE = "releasedate";
private static final String MODULE_ATTR_IS_GLOBAL = "global";
private static final String MODULE_ATTR_IS_PREFERRED_UPDATE = "preferredupdate";
private static final String MODULE_ATTR_TARGET_CLUSTER = "targetcluster";
private static final String MODULE_ATTR_EAGER = "eager";
private static final String MODULE_ATTR_AUTOLOAD = "autoload";
private static final String MODULE_ATTR_LICENSE = "license";
private static final String MANIFEST_ATTR_SPECIFICATION_VERSION = "OpenIDE-Module-Specification-Version";
private static final String MANIFEST_ATTR_FRAGMENT_HOST = "OpenIDE-Module-Fragment-Host";
private static final String L10N_ATTR_LOCALE = "langcode";
private static final String L10N_ATTR_BRANDING = "brandingcode";
private static final String L10N_ATTR_MODULE_SPECIFICATION = "module_spec_version";
private static final String L10N_ATTR_MODULE_MAJOR_VERSION = "module_major_version";
private static final String L10N_ATTR_LOCALIZED_MODULE_NAME = "OpenIDE-Module-Name";
private static final String L10N_ATTR_LOCALIZED_MODULE_DESCRIPTION = "OpenIDE-Module-Long-Description";
public static Map<String, UpdateItem> getUpdateItems (File nbmFile) throws IOException, SAXException {
Map<String, UpdateItem> items = new HashMap<String, UpdateItem> ();
try {
SAXParser saxParser = SAXParserFactory.newInstance ().newSAXParser ();
if (!isOSGiBundle(nbmFile)) {
// standard NBM
saxParser.parse(getAutoupdateInfoInputSource(nbmFile), new AutoupdateInfoParser(items, nbmFile));
} else {
// OSGi
saxParser.parse(getAutoupdateInfoInputStream(nbmFile), new AutoupdateInfoParser(items, nbmFile));
}
} catch (SAXException ex) {
ERR.log (Level.INFO, ex.getMessage (), ex);
} catch (IOException ex) {
ERR.log (Level.INFO, ex.getMessage (), ex);
} catch (ParserConfigurationException ex) {
ERR.log (Level.INFO, ex.getMessage (), ex);
}
return items;
}
private final Stack<ModuleDescriptor> currentModule = new Stack<ModuleDescriptor> ();
private final Stack<String> currentLicense = new Stack<String> ();
private final List<String> lines = new ArrayList<String> ();
@Override
public void characters (char[] ch, int start, int length) throws SAXException {
lines.add (new String(ch, start, length));
}
@Override
public void endElement (String uri, String localName, String qName) throws SAXException {
switch (ELEMENTS.valueOf (qName)) {
case module :
assert ! currentModule.empty () : "Premature end of module " + qName;
currentModule.pop ();
break;
case l10n :
break;
case manifest :
break;
case description :
ERR.info ("Not supported yet.");
break;
case module_notification :
// write module notification
ModuleDescriptor md = currentModule.peek ();
assert md != null : "ModuleDescriptor found for " + nbmFile;
StringBuilder buf = new StringBuilder ();
for (String line : lines) {
buf.append (line);
}
md.appendNotification (buf.toString ());
break;
case external_package :
ERR.info ("Not supported yet.");
break;
case license :
assert ! currentLicense.empty () : "Premature end of license " + qName;
// find and fill UpdateLicenseImpl
StringBuilder sb = new StringBuilder ();
for (String line : lines) {
sb.append (line);
}
assert currentUpdateLicenseImpl != null : "UpdateLicenseImpl found for " + nbmFile;
currentUpdateLicenseImpl.setAgreement (sb.toString ());
currentLicense.pop ();
break;
default:
ERR.warning ("Unknown element " + qName);
}
}
@Override
public void endDocument () throws SAXException {
ERR.fine ("End parsing " + nbmFile + " at " + System.currentTimeMillis ());
}
@Override
public void startDocument () throws SAXException {
ERR.fine ("Start parsing " + nbmFile + " at " + System.currentTimeMillis ());
}
@Override
public void startElement (String uri, String localName, String qName, Attributes attributes) throws SAXException {
lines.clear();
switch (ELEMENTS.valueOf (qName)) {
case module :
ModuleDescriptor md = new ModuleDescriptor (nbmFile);
md.appendModuleAttributes (attributes);
currentModule.push (md);
break;
case l10n :
// construct l10n
// XXX
break;
case manifest :
// construct module
ModuleDescriptor desc = currentModule.peek ();
desc.appendManifest (attributes);
UpdateItem m = desc.createUpdateItem ();
// put license impl to map for future refilling
UpdateItemImpl impl = Trampoline.SPI.impl (m);
currentUpdateLicenseImpl = impl.getUpdateLicenseImpl ();
// put module into UpdateItems
items.put (desc.getId (), m);
break;
case description :
ERR.info ("Not supported yet.");
break;
case module_notification :
break;
case external_package :
ERR.info ("Not supported yet.");
break;
case license :
currentLicense.push (attributes.getValue (LICENSE_ATTR_NAME));
break;
default:
ERR.warning ("Unknown element " + qName);
}
}
@Override
public InputSource resolveEntity (String publicId, String systemId) throws IOException, SAXException {
return entityResolver.resolveEntity (publicId, systemId);
}
private static class ModuleDescriptor {
private String moduleCodeName;
private String targetcluster;
private String homepage;
private String downloadSize;
private String author;
private String publishDate;
private String notification;
private String fragmentHost;
private Boolean needsRestart;
private Boolean isGlobal;
private Boolean isEager;
private Boolean isAutoload;
private Boolean isPreferredUpdate;
private String specVersion;
private Manifest mf;
private UpdateLicense lic;
private final File nbmFile;
public ModuleDescriptor (File nbmFile) {
this.nbmFile = nbmFile;
}
public void appendModuleAttributes (Attributes module) {
moduleCodeName = module.getValue (MODULE_ATTR_CODE_NAME_BASE);
targetcluster = module.getValue (MODULE_ATTR_TARGET_CLUSTER);
homepage = module.getValue (MODULE_ATTR_HOMEPAGE);
downloadSize = module.getValue (MODULE_ATTR_DOWNLOAD_SIZE);
author = module.getValue (MODULE_ATTR_MODULE_AUTHOR);
publishDate = module.getValue (MODULE_ATTR_RELEASE_DATE);
if (publishDate == null || publishDate.length () == 0) {
publishDate = Utilities.formatDate (new Date (nbmFile.lastModified ()));
}
String needsrestart = module.getValue (MODULE_ATTR_NEEDS_RESTART);
String global = module.getValue (MODULE_ATTR_IS_GLOBAL);
String eager = module.getValue (MODULE_ATTR_EAGER);
String autoload = module.getValue (MODULE_ATTR_AUTOLOAD);
String preferred = module.getValue(MODULE_ATTR_IS_PREFERRED_UPDATE);
needsRestart = needsrestart == null || needsrestart.trim ().length () == 0 ? null : Boolean.valueOf (needsrestart);
isGlobal = global == null || global.trim ().length () == 0 ? null : Boolean.valueOf (global);
isEager = Boolean.parseBoolean (eager);
isAutoload = Boolean.parseBoolean (autoload);
isPreferredUpdate = Boolean.parseBoolean(preferred);
String licName = module.getValue (MODULE_ATTR_LICENSE);
lic = UpdateLicense.createUpdateLicense (licName, null);
}
public void appendManifest (Attributes manifest) {
specVersion = manifest.getValue (MANIFEST_ATTR_SPECIFICATION_VERSION);
fragmentHost = manifest.getValue(MANIFEST_ATTR_FRAGMENT_HOST);
mf = getManifest (manifest);
}
public void appendNotification (String notification) {
this.notification = notification;
}
public String getId () {
return moduleCodeName + '_' + specVersion; // NOI18N
}
public UpdateItem createUpdateItem () {
URL distributionUrl = null;
try {
distributionUrl = org.openide.util.Utilities.toURI(nbmFile).toURL (); // nbm as a source
} catch (MalformedURLException ex) {
ERR.log (Level.INFO, null, ex);
}
UpdateItem res = UpdateItem.createModule (
moduleCodeName,
specVersion,
distributionUrl,
author,
downloadSize,
homepage,
publishDate,
null, // no group
mf,
isEager,
isAutoload,
needsRestart,
isGlobal,
isPreferredUpdate,
targetcluster,
lic);
// read module notification
UpdateItemImpl impl = Trampoline.SPI.impl(res);
((ModuleItem) impl).setModuleNotification (notification);
((ModuleItem) impl).setFragmentHost(fragmentHost);
return res;
}
}
private static Manifest getManifest (Attributes attrList) {
Manifest mf = new Manifest ();
java.util.jar.Attributes mfAttrs = mf.getMainAttributes ();
for (int i = 0; i < attrList.getLength (); i++) {
mfAttrs.put (new java.util.jar.Attributes.Name (attrList.getQName (i)), attrList.getValue (i));
}
return mf;
}
private static InputSource getAutoupdateInfoInputSource (File nbmFile) throws IOException, SAXException {
// find info.xml entry
JarFile jf = null;
try {
jf = new JarFile (nbmFile);
} catch (IOException ex) {
throw new IOException("Cannot open NBM file " + nbmFile + ": " + ex, ex);
}
String locale = Locale.getDefault ().toString ();
ZipEntry entry = jf.getEntry (INFO_DIR + '/' + INFO_LOCALE + '/' + INFO_NAME + '_' + locale + INFO_EXT);
if (entry == null) {
entry = jf.getEntry (INFO_DIR + '/' + INFO_FILE);
}
if (entry == null) {
throw new IllegalArgumentException ("info.xml found in file " + nbmFile);
}
return new InputSource (new BufferedInputStream (jf.getInputStream (entry)));
}
private static InputStream getAutoupdateInfoInputStream (File nbmFile) throws IOException, SAXException {
try {
// find info.xml entry
JarFile jf = null;
try {
jf = new JarFile (nbmFile);
} catch (IOException ex) {
throw new IOException("Cannot open NBM file " + nbmFile + ": " + ex, ex);
}
Element fakeOSGiInfoXml = fakeOSGiInfoXml(jf, nbmFile);
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
StringWriter writer = new StringWriter();
Result result = new StreamResult(writer);
Source source = new DOMSource(fakeOSGiInfoXml.getOwnerDocument());
transformer.transform(source, result);
writer.close();
String xml = writer.toString();
InputStream inputStream = new ByteArrayInputStream(xml.getBytes("UTF-8"));
return inputStream;
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
} catch (TransformerException ex) {
Exceptions.printStackTrace(ex);
}
return null;
}
private static boolean isOSGiBundle(File jarFile) {
try {
JarFile jar = new JarFile(jarFile);
Manifest mf = jar.getManifest();
return mf != null && mf.getMainAttributes().getValue("Bundle-SymbolicName") != null; // NOI18N
} catch (IOException ioe) {
ERR.log(Level.INFO, ioe.getLocalizedMessage(), ioe);
}
return false;
}
/**
* Create the equivalent of {@code Info/info.xml} for an OSGi bundle.
*
* @param jar a bundle
* @return a {@code <module ...><manifest .../></module>} valid according to
* <a href="http://www.netbeans.org/dtds/autoupdate-info-2_5.dtd">DTD</a>
*/
private static Element fakeOSGiInfoXml(JarFile jar, File whereFrom) throws IOException {
java.util.jar.Attributes attr = jar.getManifest().getMainAttributes();
Properties localized = new Properties();
String bundleLocalization = attr.getValue("Bundle-Localization");
if (bundleLocalization != null) {
InputStream is = jar.getInputStream(jar.getEntry(bundleLocalization + ".properties"));
try {
localized.load(is);
} finally {
is.close();
}
}
return fakeOSGiInfoXml(attr, localized, whereFrom);
}
public static final String BUNDLE_EXPORT_PACKAGE = "Export-Package"; // NOI18N
public static final String BUNDLE_IMPORT_PACKAGE = "Import-Package"; // NOI18N
static Element fakeOSGiInfoXml(java.util.jar.Attributes attr, Properties localized, File whereFrom) {
Document doc = XMLUtil.createDocument("module");
Element module = doc.getDocumentElement();
String cnb = extractCodeName(attr, null);
module.setAttribute("codenamebase", cnb);
module.setAttribute("distribution", ""); // seems to be ignored anyway
module.setAttribute("downloadsize", "0"); // recalculated anyway
module.setAttribute("targetcluster", whereFrom.getParentFile().getName()); // #207075 comment #3
Element manifest = doc.createElement("manifest");
module.appendChild(manifest);
manifest.setAttribute("AutoUpdate-Show-In-Client", "true"); // show me in UI
manifest.setAttribute("OpenIDE-Module", cnb);
String bundleName = loc(localized, attr, "Bundle-Name");
manifest.setAttribute("OpenIDE-Module-Name", bundleName != null ? bundleName : cnb);
String bundleVersion = attr.getValue("Bundle-Version");
manifest.setAttribute("OpenIDE-Module-Specification-Version",
bundleVersion != null ? bundleVersion.replaceFirst("^(\\d+([.]\\d+([.]\\d+)?)?)([.].+)?$", "$1") : "0");
String requireBundle = attr.getValue("Require-Bundle");
if (requireBundle != null) {
StringBuilder b = new StringBuilder();
boolean needsNetbinox = false;
// http://stackoverflow.com/questions/1757065/java-splitting-a-comma-separated-string-but-ignoring-commas-in-quotes
for (String dep : requireBundle.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)")) {
Matcher m = Pattern.compile("([^;]+)(.*)").matcher(dep);
if (!m.matches()) {
throw new RuntimeException("Could not parse dependency: " + dep + " in " + whereFrom);
}
String requiredBundleName = m.group(1); // dep CNB
if (requiredBundleName.trim().equals("org.eclipse.osgi")) {
needsNetbinox = true;
continue;
}
Matcher m2 = Pattern.compile(";([^:=]+):?=\"?([^;\"]+)\"?").matcher(m.group(2));
boolean isOptional = false;
while (m2.find()) {
if (m2.group(1).equals("resolution") && m2.group(2).equals("optional")) {
isOptional = true;
break;
}
}
if (isOptional) {
continue;
}
m2.reset();
if (b.length() > 0) {
b.append(", ");
}
b.append(requiredBundleName); // dep CNB
while (m2.find()) {
if (!m2.group(1).equals("bundle-version")) {
continue;
}
String val = m2.group(2);
if (val.matches("[0-9]+([.][0-9]+)*")) {
// non-range dep occasionally used in OSGi; no exact equivalent in NB
b.append(" > ").append(val);
continue;
}
Matcher m3 = Pattern.compile("\\[([0-9]+)((?:[.][0-9]+)*),([0-9.]+)\\)").matcher(val);
if (!m3.matches()) {
throw new RuntimeException("Could not parse version range: " + val + " in " + whereFrom);
}
int major = Integer.parseInt(m3.group(1));
String rest = m3.group(2);
try {
int max = Integer.parseInt(m3.group(3));
if (major > 99) {
b.append('/').append(major / 100);
if (max > major + 100) {
b.append('-').append(max / 100 - 1);
}
} else if (max > 100) {
b.append("/0-").append(max / 100 - 1);
}
} catch (NumberFormatException x) {
// never mind end boundary, does not match NB conventions
}
b.append(" > ").append(major % 100).append(rest);
}
}
if (b.length() > 0) {
manifest.setAttribute("OpenIDE-Module-Module-Dependencies", b.toString());
}
if (needsNetbinox) {
manifest.setAttribute("OpenIDE-Module-Needs", "org.netbeans.Netbinox");
}
}
String pp = attr.getValue(BUNDLE_EXPORT_PACKAGE);
StringBuilder provides = new StringBuilder();
if (pp != null) {
for (String p : pp.replaceAll("\"[^\"]*\"", "").split(",")) {
if (provides.length() > 0) {
provides.append(',');
}
provides.append(p.replaceAll(";.*$", "").trim());
}
}
if (provides.length() > 0) {
manifest.setAttribute("OpenIDE-Module-Provides", provides.toString());
}
String ip = attr.getValue(BUNDLE_IMPORT_PACKAGE);
StringBuilder recommends = new StringBuilder();
if (ip != null) {
for (String p : ip.replaceAll("\"[^\"]*\"", "").split(",")) {
String pkg = p.replaceAll(";.*$", "").trim();
if (JAVA_PLATFORM_PACKAGES.contains(pkg)) {
continue;
}
if (recommends.length() > 0) {
recommends.append(',');
}
recommends.append(p.replaceAll(";.*$", "").trim());
}
}
if (recommends.length() > 0) {
manifest.setAttribute("OpenIDE-Module-Recommends", recommends.toString().replace('-', '_'));
}
String bundleCategory = loc(localized, attr, "Bundle-Category");
if (bundleCategory != null) {
manifest.setAttribute("OpenIDE-Module-Display-Category", bundleCategory);
}
String bundleDescription = loc(localized, attr, "Bundle-Description");
if (bundleDescription != null) {
manifest.setAttribute("OpenIDE-Module-Short-Description", bundleDescription);
}
// XXX anything else need to be set?
return module;
}
private static String loc(Properties localized, java.util.jar.Attributes attr, String key) {
String val = attr.getValue(key);
if (val == null) {
return null;
} else if (val.startsWith("%")) {
return localized.getProperty(val.substring(1));
} else {
return val;
}
}
private static String extractCodeName(java.util.jar.Attributes attr, boolean[] osgi) {
String codename = attr.getValue("OpenIDE-Module");
if (codename != null) {
return codename;
}
codename = attr.getValue("Bundle-SymbolicName");
if (codename == null) {
return null;
}
codename = codename.replace('-', '_');
if (osgi != null) {
osgi[0] = true;
}
int params = codename.indexOf(';');
if (params >= 0) {
return codename.substring(0, params);
} else {
return codename;
}
}
/**
* List of packages guaranteed to be in the Java platform;
* taken from JDK 6 Javadoc package-list after removing java.* packages.
* Note that Felix's default.properties actually includes a few more packages
* (such as org.w3c.dom.ranges) which can be found in src.zip but are not documented.
* COPIED FROM: MakeOSGi
*/
private static final Set<String> JAVA_PLATFORM_PACKAGES = new TreeSet<String>(Arrays.asList(
"javax.accessibility",
"javax.activation",
"javax.activity",
"javax.annotation",
"javax.annotation.processing",
"javax.crypto",
"javax.crypto.interfaces",
"javax.crypto.spec",
"javax.imageio",
"javax.imageio.event",
"javax.imageio.metadata",
"javax.imageio.plugins.bmp",
"javax.imageio.plugins.jpeg",
"javax.imageio.spi",
"javax.imageio.stream",
"javax.jws",
"javax.jws.soap",
"javax.lang.model",
"javax.lang.model.element",
"javax.lang.model.type",
"javax.lang.model.util",
"javax.management",
"javax.management.loading",
"javax.management.modelmbean",
"javax.management.monitor",
"javax.management.openmbean",
"javax.management.relation",
"javax.management.remote",
"javax.management.remote.rmi",
"javax.management.timer",
"javax.naming",
"javax.naming.directory",
"javax.naming.event",
"javax.naming.ldap",
"javax.naming.spi",
"javax.net",
"javax.net.ssl",
"javax.print",
"javax.print.attribute",
"javax.print.attribute.standard",
"javax.print.event",
"javax.rmi",
"javax.rmi.CORBA",
"javax.rmi.ssl",
"javax.script",
"javax.security.auth",
"javax.security.auth.callback",
"javax.security.auth.kerberos",
"javax.security.auth.login",
"javax.security.auth.spi",
"javax.security.auth.x500",
"javax.security.cert",
"javax.security.sasl",
"javax.sound.midi",
"javax.sound.midi.spi",
"javax.sound.sampled",
"javax.sound.sampled.spi",
"javax.sql",
"javax.sql.rowset",
"javax.sql.rowset.serial",
"javax.sql.rowset.spi",
"javax.swing",
"javax.swing.border",
"javax.swing.colorchooser",
"javax.swing.event",
"javax.swing.filechooser",
"javax.swing.plaf",
"javax.swing.plaf.basic",
"javax.swing.plaf.metal",
"javax.swing.plaf.multi",
"javax.swing.plaf.synth",
"javax.swing.table",
"javax.swing.text",
"javax.swing.text.html",
"javax.swing.text.html.parser",
"javax.swing.text.rtf",
"javax.swing.tree",
"javax.swing.undo",
"javax.tools",
"javax.transaction",
"javax.transaction.xa",
"javax.xml",
"javax.xml.bind",
"javax.xml.bind.annotation",
"javax.xml.bind.annotation.adapters",
"javax.xml.bind.attachment",
"javax.xml.bind.helpers",
"javax.xml.bind.util",
"javax.xml.crypto",
"javax.xml.crypto.dom",
"javax.xml.crypto.dsig",
"javax.xml.crypto.dsig.dom",
"javax.xml.crypto.dsig.keyinfo",
"javax.xml.crypto.dsig.spec",
"javax.xml.datatype",
"javax.xml.namespace",
"javax.xml.parsers",
"javax.xml.soap",
"javax.xml.stream",
"javax.xml.stream.events",
"javax.xml.stream.util",
"javax.xml.transform",
"javax.xml.transform.dom",
"javax.xml.transform.sax",
"javax.xml.transform.stax",
"javax.xml.transform.stream",
"javax.xml.validation",
"javax.xml.ws",
"javax.xml.ws.handler",
"javax.xml.ws.handler.soap",
"javax.xml.ws.http",
"javax.xml.ws.soap",
"javax.xml.ws.spi",
"javax.xml.ws.wsaddressing",
"javax.xml.xpath",
"org.ietf.jgss",
"org.omg.CORBA",
"org.omg.CORBA.DynAnyPackage",
"org.omg.CORBA.ORBPackage",
"org.omg.CORBA.TypeCodePackage",
"org.omg.CORBA.portable",
"org.omg.CORBA_2_3",
"org.omg.CORBA_2_3.portable",
"org.omg.CosNaming",
"org.omg.CosNaming.NamingContextExtPackage",
"org.omg.CosNaming.NamingContextPackage",
"org.omg.Dynamic",
"org.omg.DynamicAny",
"org.omg.DynamicAny.DynAnyFactoryPackage",
"org.omg.DynamicAny.DynAnyPackage",
"org.omg.IOP",
"org.omg.IOP.CodecFactoryPackage",
"org.omg.IOP.CodecPackage",
"org.omg.Messaging",
"org.omg.PortableInterceptor",
"org.omg.PortableInterceptor.ORBInitInfoPackage",
"org.omg.PortableServer",
"org.omg.PortableServer.CurrentPackage",
"org.omg.PortableServer.POAManagerPackage",
"org.omg.PortableServer.POAPackage",
"org.omg.PortableServer.ServantLocatorPackage",
"org.omg.PortableServer.portable",
"org.omg.SendingContext",
"org.omg.stub.java.rmi",
"org.w3c.dom",
"org.w3c.dom.bootstrap",
"org.w3c.dom.events",
"org.w3c.dom.ls",
"org.xml.sax",
"org.xml.sax.ext",
"org.xml.sax.helpers"
));
}