Slim3でBlazeDSのserviceインスタンスがHotReloading下のオブジェクトを触れるようにしたい
とりあえず動いたのでコードを載せておきます。自前のドメインを持っていないので、会社のドメインだけど気にしないでください。
slim3もBlazeDSもちゃんと深くコードを読んだ訳ではないので動作保障は全くしません。
一応目的としては、HotReloading下のインスタンスに触っても怒られないことと、サービスをxmlに書かなくても動作させること。
セットアップはS2BlazeDSと同じ感じにAdapterとEndpointをservices-configあたりに。
HotReloadingに対応、というよりもタイトル通り「なんかよくわからんけどDatastoreに触ってもCastの例外出ないし、ソース変更して保存したら動作も変わるしおk」的なノリ
S3Adapter.java
/* * Copyright 2004-2008 the Seasar Foundation and the Others. * * Licensed 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 jp.archilogic.slim3.blazeds; import flex.messaging.Destination; import flex.messaging.services.remoting.RemotingDestination; import flex.messaging.services.remoting.adapters.JavaAdapter; /** * Adapter for slim3 * * @author higa * @author funnything * @see org.seasar.blazeds.adapters.S2Adapter * */ public class S3Adapter extends JavaAdapter { @Override public void setDestination(Destination destination) { RemotingDestination dest = (RemotingDestination) destination; dest.setFactory(new S3Factory()); super.setDestination(dest); } }
S3AMFEndpoint.java
/* * Copyright 2004-2008 the Seasar Foundation and the Others. * * Licensed 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 jp.archilogic.slim3.blazeds; import flex.messaging.endpoints.AMFEndpoint; import flex.messaging.messages.Message; import flex.messaging.services.RemotingService; import flex.messaging.services.remoting.RemotingDestination; /** * AMFEndpoint for slim3 * * @author higa * @author funnything * @see org.seasar.blazeds.endpoints.S2AMFEndpoint * */ public class S3AMFEndpoint extends AMFEndpoint { public S3AMFEndpoint() { } /** * @param enableManagement * enable jmx management */ public S3AMFEndpoint(boolean enableManagement) { // TODO Couldn't set manageble = false here? // ( to remove manageable tag on services-config.xml ) super(enableManagement); } @Override public Message serviceMessage(Message message) { RemotingService remotingService = (RemotingService) getMessageBroker().getService("remoting-service"); synchronized (remotingService) { RemotingDestination destination = (RemotingDestination) remotingService.getDestination(message .getDestination()); if (destination == null) { destination = (RemotingDestination) remotingService .createDestination(message.getDestination()); destination.setChannels(remotingService.getDefaultChannels()); destination.createAdapter(remotingService.getDefaultAdapter()); remotingService.addDestination(destination); destination.start(); } } return super.serviceMessage(message); } }
S2BlazeDSとほぼ同じ。何が来てもチェックせずに通してます。
S3Factory.java
/* * Copyright 2004-2008 the Seasar Foundation and the Others. * * Licensed 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 jp.archilogic.slim3.blazeds; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletContext; import org.slim3.controller.ControllerConstants; import org.slim3.util.ClassUtil; import org.slim3.util.ServletContextLocator; import org.slim3.util.StringUtil; import flex.messaging.FactoryInstance; import flex.messaging.config.ConfigMap; import flex.messaging.factories.JavaFactory; /** * Factory for slim3 * * @author higa * @author funnything * @see org.slim3.controller.FrontController */ public class S3Factory extends JavaFactory { private final static Logger logger = Logger.getLogger(S3Factory.class.getName()); /** * The servlet context. */ protected ServletContext servletContext; /** * The root package name. */ protected String rootPackageName; public S3Factory() { super(); // TODO is this valid? servletContext = ServletContextLocator.get(); initRootPackageName(); } @Override public FactoryInstance createFactoryInstance(String id, ConfigMap configMap) { return new S3FactoryInstance(this, id, configMap); } /** * Returns the service package name. * * @return the service package name */ protected String getServicePackageName() { String packageName = (String) servletContext .getAttribute(ServiceConstants.SERVICE_PACKAGE_KEY); if (packageName == null) { packageName = ServiceConstants.DEFAULT_SERVICE_PACKAGE; } return packageName; } /** * Initializes the root package name. */ protected void initRootPackageName() { rootPackageName = servletContext .getInitParameter(ControllerConstants.ROOT_PACKAGE_KEY); if (StringUtil.isEmpty(rootPackageName)) { throw new IllegalStateException("The context-param(" + ControllerConstants.ROOT_PACKAGE_KEY + ") is not found in web.xml."); } } /** * Find proper component * * @param factoryInstance * faccotyInstance * @return null if not found the component */ @Override public Object lookup(FactoryInstance factoryInstance) { String className = toServiceClassName(factoryInstance.getId()); System.err.println(className); Class<?> clazz = null; ClassLoader loader = Thread.currentThread().getContextClassLoader(); try { clazz = Class.forName(className, true, loader); } catch (Throwable t) { if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, t.getMessage(), t); } return null; } return ClassUtil.newInstance(clazz); } /** * Converts the path to the service class name. * * @param id * destination id * @return the service class name * @throws IllegalStateException * if the system property(slim3.controllerPackage) is not found */ protected String toServiceClassName(String id) throws IllegalStateException { String className = rootPackageName + "." + getServicePackageName() + "." + id; int pos = className.lastIndexOf('.'); if (className.endsWith(".")) { throw new IllegalArgumentException( "Destination id must not end with comma."); } className = className.substring(0, pos + 1) + StringUtil.capitalize(className.substring(pos + 1)) + ServiceConstants.SERVICE_SUFFIX; return className; } }
serviceパッケージ以下のクラスを探すように。コンテナが無いから毎回ローディングしてるんですが、どうなのこれ
S3FactoryInstance.java
/* * Copyright 2004-2008 the Seasar Foundation and the Others. * * Licensed 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 jp.archilogic.slim3.blazeds; import flex.messaging.FlexConfigurable; import flex.messaging.config.ConfigMap; import flex.messaging.factories.JavaFactory; import flex.messaging.factories.JavaFactoryInstance; import flex.messaging.util.ClassUtil; /** * FactoryInstance for slim3 ( This code is same as * org.seasar.blazeds.factories.S2FactoryInstance ) * * @author higa * */ public class S3FactoryInstance extends JavaFactoryInstance { public S3FactoryInstance(JavaFactory factory, String id, ConfigMap properties) { super(factory, id, properties); } @Override public Object createInstance() { Class clazz = getInstanceClass(); if (clazz == null) { return null; } Object inst = ClassUtil.createDefaultInstance(clazz, null); if (inst instanceof FlexConfigurable) ((FlexConfigurable) inst).initialize(getId(), getProperties()); return inst; } @Override public Class getInstanceClass() { if (getSource() == null) { return null; } return super.getInstanceClass(); } }
ServiceConstants.java
package jp.archilogic.slim3.blazeds; public interface ServiceConstants { /** * The suffix of service. */ String SERVICE_SUFFIX = "Service"; /** * The key of controller package. */ String SERVICE_PACKAGE_KEY = "slim3.servicePackage"; /** * The default service package name. */ String DEFAULT_SERVICE_PACKAGE = "service"; }
眠気がMAXなので寝ます